JS / Lodash-替换多维对象中的值

时间:2018-07-04 13:35:01

标签: javascript arrays json ecmascript-6 lodash

我正在寻找一种有效的方法,以使用Lodash甚至香草JS替换多维对象中的值。

我有一个数组,其中包含未知深度的多维对象,例如(简化)

objects = [{
    id: 1,
    view: {
        id: 7
    }
}, {
    id: 2,
    view: {
        id: 9
    },
    childs: [{
        id: 3,
        view: {
            id: 3
        }
    }]
}];

现在,我想用存储在单独对象中的命名导入引用替换每个节点的view值。这些引用可以通过view.id作为此对象的索引进行访问。所以我想要达到的目标是这样的

views = {
    3: some,
    7: random,
    9: imports
};

objects = [{
    id: 1,
    view: views[7]
}, {
    ...
}];

好吧,我知道如何遍历多维对象以手动实现此目的,但是由于我正在处理大型对象,因此,如果使用Lodash将有一种更清洁,更高效的方式,那就太好了。

有人有天才的解决方案吗?

2 个答案:

答案 0 :(得分:1)

由于lodash只是用JS编写的实用程序层,因此使用它不可能获得比普通JS更高的性能。

下面的功能可能是完成所需操作的最快方法:它会突变提供的对象而不是创建新对象,并且不会遍历每个键。

function transform(arr) {
  arr.forEach(obj => {
    if (obj.hasOwnProperty('view')) obj.view = views[obj.view.id];
    if (obj.hasOwnProperty('childs')) transform(obj.childs);
  });
}

答案 1 :(得分:0)

您可以使用递归_.transform()调用来迭代和更新对象的视图:

const fn = o => _.transform(o, (acc, v, k) => {
  // if key is view, and it and has an id value replace it with equivalent from views
  if(_.eq(k, 'view') && _.has(v, 'id')) acc[k] = _.get(views, v.id, v);
  
  // if it's an object transform it recursively
  else if (_.isObject(v)) acc[k] = fn(v);
  
  // assign primitives to accumulator
  else acc[k] = v;
});

const objects = [{"id":1,"view":{"id":7}},{"id":2,"view":{"id":9},"childs":[{"id":3,"view":{"id":3}}]}];

const views = {
    3: 'some',
    7: 'random',
    9: 'imports'
};

const result = fn(objects);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>