我有一组多维对象:
var arr = [
{
id: '10c',
name: 'item 1'
children: [
{id: '11v', name: 'Item 1 child 1'},
{id: '12c', name: 'Item 1 child 2'}
]
},
{
id: '13v',
name: 'item 2'
children: [
{id: '26e', name: 'Item 2 child 1'},
{id: '7a', name: 'Item 2 child 2'}
]
}
]
和另一个数据对象:
var array = [
{id: '12c', name: 'New name 1'},
{id: '26e', name: 'New name 2'},
{id: '11v', name: 'New name 3'},
];
如果我想根据name
中的arr
值更新id
中相应对象的array
值,那么最好的做法是什么?是什么?
arr
可能超过2个级别,所以我希望能够在不必嵌套多个forEach
答案 0 :(得分:3)
试试这个:
function update(items, id, name) {
var item;
for (var i = 0; i < items.length; i++) {
item = items[i];
if (item.id === id) {
item.name = name;
return;
}
if (item.children) {
update(item.children, id, name);
}
}
}
然后:
update(arr, '11v', 'test');
按array
更新:
array.forEach(function (item) {
update(arr, item.id, item.name);
});
答案 1 :(得分:0)
使用递归解决方案并利用Javascript的固有可变性。
首先建立所有对象的平面地图表示。
function createObjectMap(array) {
var map = {};
array.forEach(function(obj) {
map[obj.id] = obj;
if(obj.children) {
Object.assign(map, createObjectMap(obj.children));
}
});
return map;
}
现在你已经有了id -> object
你可以使用的地图了。它们引用相同的可变对象,因此您可以在适当的位置对它们进行变异,并知道它们也将在原始数据结构中进行更新。
function update(map, updates) {
updates.forEach(function(update) {
map[update.id].name = update.name;
});
}
这种转换为O(1)查找时间意味着您不必编写任何搜索逻辑。
答案 2 :(得分:0)
您可以使用角度$ filter来执行相同的操作
//to get element
function getFiltered(collection, obj){
var filtered = $filter('filter')(collection, obj, true);
if(filtered[0])
return filtered[0]
if(collection.children)
return getFiltered(collection.children, obj, true);
}
angular.forEach(array, function(element){
var filtered = getFiltered(array, { id: element.id })
if(filtered[0]) filtered.name = element.name;
})