我使用lodash mapKeys
获取我的对象数组,并使用id
属性将其转换为映射对象。这很简单,但问题是它按id
对新对象进行排序。
例如,如果我的数组中有三个对象:
let myArray = [
{
id: 3,
name: 'Number Three'
},
{
id: 1,
name: 'Number One'
},
{
id: 2,
name: 'Number Two'
}
];
然后我按id
映射键:
_.mapKeys(myArray, 'id')
返回以下内容:
{
1: {
id: 1,
name: 'Number One'
},
2: {
id: 2,
name: 'Number Two'
},
3: {
id: 3,
name: 'Number Three'
}
}
我的服务器以特定的顺序返回数组,所以我希望这些对象保持不变,这样当我遍历对象属性时,它们的顺序正确。
这种方法有可能吗?如果没有,是否有可能的替代方案来实现结果?
答案 0 :(得分:1)
使用Map
,因为每个项目都有自定义键(如对象),但插入顺序将是迭代的顺序(如数组):
const myArray = [
{
id: 3,
name: 'Number Three'
},
{
id: 1,
name: 'Number One'
},
{
id: 2,
name: 'Number Two'
}
];
const map = myArray.reduce((map, item) => map.set(item.id, item), new Map());
map.forEach((item) => console.log(item));
答案 1 :(得分:0)
如评论中所提到的,最好的方法是将对象引用保留在数组中以保持顺序,并使用哈希来简化更新。
Backbone's collection(source)就是这样的。它将对象保留在数组(models
)中,但在添加和删除模型(对象)时或模型的ID更改时自动更新哈希(_byId
)。
这是概念的简单实现。您可以进行自己的实现或检查集合库。
// a little setup
var array = [];
var hash = {};
var addObject = function addObject(obj) {
hash[obj.id] = obj;
array.push(obj);
}
// Create/insert the objects once
addObject({ id: 3, name: 'Number Three' });
addObject({ id: 1, name: 'Number One' });
addObject({ id: 2, name: 'Number Two' });
// Easy access by id
console.log("by id with hash", hash['1']);
// updating is persistent with the object in the array
hash['1'].name += " test";
// keeps the original ordering
for (var i = 0; i < 3; ++i) {
console.log("iterating", i, array[i]);
}
&#13;
答案 2 :(得分:0)
正如评论中所指出的,循环对象并不能保证秩序。如果你想要一个有序列表,你需要一个数组。
但是,您可以应用迭代器模式。在这种模式中,由您来决定“下一个”元素是什么。因此,您可以拥有一个包含对象的集合(为了使它们保持恒定时间)和一个用于存储订单的数组。要迭代,您可以使用迭代器。
此代码可用作示例。
希望它有所帮助。
let myArray = [{
id: 3,
name: 'Number Three'
}, {
id: 1,
name: 'Number One'
}, {
id: 2,
name: 'Number Two'
}];
let myIterator = ((arr) => {
let mySet = _.mapKeys(arr, 'id'),
index = 0,
myOrder = _.map(arr, _.property('id'));
return {
getObjById: (id) => mySet[id],
next: () => mySet[myOrder[index++]],
hasNext: () => index < myOrder.length
};
})(myArray);
// Access elements by id in constant time.
console.log(myIterator.getObjById(1));
// Preserve the order that you got from your server.
while (myIterator.hasNext()) {
console.log(myIterator.next());
}
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
&#13;