更新嵌套数组中的多个对象

时间:2016-02-11 13:22:32

标签: javascript arrays angularjs lodash

我有一组多维对象:

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

的情况下执行此操作

3 个答案:

答案 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;
})