0

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?

2 Answers 2

1

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);
  });
}
Sign up to request clarification or add additional context in comments.

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.