admin管理员组

文章数量:1287488

Given this example using lodash:

var object = {};
_.set(object, [ 1, 2 ], 5);
console.log(object);

The resultant object in the console is:

{
  1: [undefined, undefined, 5]
}

Now imagine, instead of the integer 2, you are setting a timestamp of 1445231475. You now have 1445231474 undefined values in a very large array that will run out of memory after a few _.set operations.

If possible with _.set, how would one go about creating this object:

{
  1: {
    2: 5
  }
}

It is possible if 2 is truly a string like "a", but Lodash will force even "2" into the array of multiple undefined values.

I can use _.merge if necessary, but I would be more excited about using _.set capability.

Given this example using lodash:

var object = {};
_.set(object, [ 1, 2 ], 5);
console.log(object);

The resultant object in the console is:

{
  1: [undefined, undefined, 5]
}

Now imagine, instead of the integer 2, you are setting a timestamp of 1445231475. You now have 1445231474 undefined values in a very large array that will run out of memory after a few _.set operations.

If possible with _.set, how would one go about creating this object:

{
  1: {
    2: 5
  }
}

It is possible if 2 is truly a string like "a", but Lodash will force even "2" into the array of multiple undefined values.

I can use _.merge if necessary, but I would be more excited about using _.set capability.

Share Improve this question edited Aug 17, 2018 at 13:37 random_user_name 26.2k7 gold badges80 silver badges118 bronze badges asked Oct 19, 2015 at 6:28 ryanmryanm 2,26824 silver badges31 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

you can do this with lodash setWith

// unwanted behavior with set
let x = {}
_.set(x, [1,2], 'test')
// x = { '1': [ <2 empty items>, 'test' ] }

// desired behavior with setWith
let y = {}
_.setWith(y, [1,2], 'test', Object)
// y = { '1': { '2': 'test' } }

Apparently, no, it's not possible to do that, and here's why:

Within _.set, this is the relevant part:

if (index == lastIndex) {
  nested[key] = value;
} else if (nested[key] == null) {
  nested[key] = isIndex(path[index + 1]) ? [] : {};
}

What happens here is that whenever a path item doesn't exist as a key, it is tested if it is a valid index (is of type number, or matches /^\d+$/) and if so an array is created, otherwise an object.

Because key is a string, and the goal is to set a property named 2 (or any other numerical value), it will always return true from isIndex and will results in an array.

本文标签: javascriptHow to use lodash to deep set without creating undefined valuesStack Overflow