简体   繁体   中英

JS/Lodash - replace values in multidimensional object

I am looking for an efficient way to replace values within a multidimensional object using Lodash or even vanilla JS.

I have an array with multidimensional objects of unknown depth like (simplified)

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

Now I want to replace the value of view of each node with a named import reference stored in a separate object. The references are accessible through the view.id as index of this object. So what I am trying to achieve is something like this

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

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

Well I know how to iterate over a multidimensional object to achieve this manually but since I am working with large objects it would be nice if there would be a cleaner and more performant way using Lodash.

Does anybody have a genius solution?

Since lodash is just a utility layer written in JS, you're unlikely to get any performance gains over vanilla JS from using it.

The function below is probably the fastest way to do what you want: it mutates the supplied objects instead of creating new ones, and does not iterate over every key.

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

You can use a recursive _.transform() call to iterate and updated the objects' views:

 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> 

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM