在javascript数组中查找并修改深层嵌套对象

Mar*_*ark 2 javascript lodash

我有一个对象数组,可以是任何长度和任何深度.我需要能够通过其id找到一个对象,然后在数组中修改该对象.有没有一种有效的方法用lodash或纯js做到这一点?

我以为我可以创建一个导致该对象的索引数组,但构造表达式以使用这些索引访问该对象似乎过于复杂/不必要

EDIT1; 感谢你的所有回复我会尝试更具体.我目前正在寻找我试图修改的对象的位置.parents是目标对象拥有的每个父级的id数组.祖先可能是这个数组的更好名称.costCenters是包含我要修改的对象的对象数组.此函数recurses并返回一个索引数组,这些索引将指向我想要修改的对象

var findAncestorsIdxs = function(parents, costCenters, startingIdx, parentsIdxs) {
            var idx = startingIdx ? startingIdx : 0;
            var pidx = parentsIdxs ? parentsIdxs : [];

            _.each(costCenters, function(cc, ccIdx) {
                if(cc.id === parents[idx]) {
                    console.log(pidx);
                    idx = idx + 1;
                    pidx.push(ccIdx);
                    console.log(pidx);
                    pidx = findAncestorsIdx(parents, costCenters[ccIdx].children, idx, pidx);
                }
            });
            return pidx;
        }; 
Run Code Online (Sandbox Code Playgroud)

现在有了这个索引数组,我如何定位和修改我想要的确切对象?我试过这个,其中祖先是索引数组,costCenters是要修改对象的数组,parent是要分配给目标对象的新值

var setParentThroughAncestors = function(ancestors, costCenters, parent) {
            var ccs = costCenters;
            var depth = ancestors.length;
            var ancestor = costCenters[ancestors[0]];
            for(i = 1; i < depth; i++) {
                ancestor = ancestor.children[ancestors[i]];
            }
            ancestor = parent;
            console.log(ccs);
            return ccs;
        };
Run Code Online (Sandbox Code Playgroud)

这显然只是返回未修改的costCenters数组,所以我能看到的唯一另一种方法就是构造像myObjects这样的表达式[idx1] .children [2] .grandchildren [3] .ggranchildren [4] .something = newValue .这是唯一的方法吗?如果是这样,最好的方法是什么?

小智 12

你可以用JSON.stringify它.它为每个访问的键/值对(在任何深度)提供回调,并具有跳过或替换的能力.

下面的函数返回一个函数,该函数搜索具有指定ID的对象并对它们调用指定的转换回调:

function scan(id, transform) {
  return function(obj) {
    return JSON.parse(JSON.stringify(obj, function(key, value) {
      if (typeof value === 'object' && value !== null && value.id === id) {
        return transform(value);
      } else {
        return value;
      }
  }));
}
Run Code Online (Sandbox Code Playgroud)

如果问题已经陈述,你有一个对象数组,每个对象的并行数组,其中包含要修改的对象,以及一个转换函数数组,那么只需将上面的内容包装为

for (i = 0; i < objects.length; i++) {
    scan(ids[i], transforms[i])(objects[i]);
}
Run Code Online (Sandbox Code Playgroud)

由于JSON.stringify的限制,如果对象中存在循环引用,则此方法将失败,并且如果您关心,则省略函数,正则表达式和符号键控属性.

有关详细信息,请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_native_JSON#The_replacer_parameter.

  • 太好了!不知道`JSON.stringify`可以接受回调. (4认同)