Found this excellent code for _.get
vanilla js implementation:
JavaScript
x
3
1
const get = (obj, path, defaultValue) => path.split(".")
2
.reduce((a, c) => (a && a[c] ? a[c] : (defaultValue || null)), obj)
3
Now I’m looking for _.set
implementation, any help would be appreciated.
Advertisement
Answer
I think this could cover it:
JavaScript
1
20
20
1
const set = (obj, path, value) => {
2
if (Object(obj) !== obj) return obj; // When obj is not an object
3
// If not yet an array, get the keys from the string-path
4
if (!Array.isArray(path)) path = path.toString().match(/[^.[]]+/g) || [];
5
path.slice(0,-1).reduce((a, c, i) => // Iterate all of them except the last one
6
Object(a[c]) === a[c] // Does the key exist and is its value an object?
7
// Yes: then follow that path
8
? a[c]
9
// No: create the key. Is the next key a potential array-index?
10
: a[c] = Math.abs(path[i+1])>>0 === +path[i+1]
11
? [] // Yes: assign a new array object
12
: {}, // No: assign a new plain object
13
obj)[path[path.length-1]] = value; // Finally assign the value to the last key
14
return obj; // Return the top-level object to allow chaining
15
};
16
17
// Demo
18
var obj = { test: true };
19
set(obj, "test.1.it", "hello");
20
console.log(obj); // includes an intentional undefined value
It is a bit more complex than get
, because there is some logic needed to create missing parts of the path in the object, to overwrite primitive values that stand in the way, and to determine whether a new child should better be an array or a plain object.