Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Push an element anywhere in an object with Lodash

I am using lodash to manipulate a JSON object. I am not against using Vanilla JS but since I am working on a PoC for now, I am just looking for the fastest solution to test.

So here is the problem I am facing: I want to be able to easily push an element to an array anywhere in an object, and it should create automatically all the missing nodes, including the last array.

For example, let's say I have an empty object, and I would like to create a function that can populate my object with the right values, for example:

let dl = {};

customPush(dl, 'a.b', { c: 3, d: 4 });
// or
customPush(dl, ['a', 'b'], { c: 3, d: 4 });

Should create:

dl = {
  a: {
    b: [{
      c: 3,
      d: 4
    }]
  }
}

This is everything I tried but none of them are working:

function customPush(obj, path, item) {
  // This is just assigning the item to the path, not pushing to a new array
  _.set(dl, path, item);

  // This one is not doing anything visible
  _.get(dl, path, []).push(item);

  // Pushing in this one doesn't work with a path like 'a.b'
  if (_.has(dl, path)) {
    dl.path.push(item);
  } else {
    _.set(dl, path, [item]);
  }

  // Any idea?
  ...
}

Thank you very much for your help.

like image 678
Armel Avatar asked Sep 02 '25 07:09

Armel


1 Answers

Your attempt here is very close:

// Pushing in this one doesn't work with a path like 'a.b'
if (_.has(dl, path)) {
  dl.path.push(item);
} else {
  _.set(dl, path, [item]);
}

You simply need to use _.get if the array is there and _.set if it isn't. You are already doing the latter part.

function customPush(obj, path, item) {
  if (_.has(obj, path)) {
    let arr = _.get(obj, path);
    arr.push(item)
  } else {
    _.set(obj, path, [item]);
  }
}

let objOne = { }
let objTwo = { a: [] }

let objThree = { 
  a: {
    b: {
      c: {
      }
    }
  }
}

let objFour = {
  a: {
    b: {
      c: {
        d: []
      }
    }
  }
}

customPush(objOne, "a", "item");
console.log("objOne", objOne);

customPush(objTwo, "a", "item");
console.log("objTwo", objTwo);

customPush(objThree, "a.b.c.d", "item");
console.log("objThree", objThree);

customPush(objFour, "a.b.c.d", "item");
console.log("objFour", objFour);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Worth noting that this only works if the key either doesn't exist or it it's value is an array. If you give the path to an existing key with a non-array value you'd get an error. You can check that using _.isArray but I am not sure what you want to do if a key exists and does not hold an array.

like image 116
VLAZ Avatar answered Sep 04 '25 20:09

VLAZ