I have an array of multi dimensional objects:
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'}
]
}
]
and another object of data:
var array = [
{id: '12c', name: 'New name 1'},
{id: '26e', name: 'New name 2'},
{id: '11v', name: 'New name 3'},
];
If I want to update the name
value of the respective objects in arr
, based on the id
value in array
, how would be the best way of doing that?
arr
might be more than 2 levels deep, so I would like to be able to do it without having to nest multiple forEach
Try this:
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);
}
}
}
Then:
update(arr, '11v', 'test');
Updating by array
:
array.forEach(function (item) {
update(arr, item.id, item.name);
});
Use a recursive solution and make use of the inherent mutability of Javascript.
First build up a flat map representation of all the objects.
function createObjectMap(array) {
var map = {};
array.forEach(function(obj) {
map[obj.id] = obj;
if(obj.children) {
Object.assign(map, createObjectMap(obj.children));
}
});
return map;
}
Now you've got a map of id -> object
you can use. They reference the same mutable objects, so you can mutate them in place and know that they'll also update in the original data structure.
function update(map, updates) {
updates.forEach(function(update) {
map[update.id].name = update.name;
});
}
This conversion to O(1) lookup time means you don't have to write any searching logic.
You could use angular $filter to do the same
//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;
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.