Реализация javascript метода "set" lodash - PullRequest
0 голосов
/ 17 февраля 2019

Найден этот отличный код для _.get реализации vanilla js:

const get = (obj, path, defaultValue) => path.split(".")
.reduce((a, c) => (a && a[c] ? a[c] : (defaultValue || null)), obj)

Сейчас я ищу _.set реализацию, любая помощь будет оценена.

1 Ответ

0 голосов
/ 17 февраля 2019

Я думаю, что это может охватить это:

const set = (obj, path, value) => {
    if (Object(obj) !== obj) return obj; // When obj is not an object
    // If not yet an array, get the keys from the string-path
    if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || []; 
    path.slice(0,-1).reduce((a, c, i) => // Iterate all of them except the last one
         Object(a[c]) === a[c] // Does the key exist and is its value an object?
             // Yes: then follow that path
             ? a[c] 
             // No: create the key. Is the next key a potential array-index?
             : a[c] = Math.abs(path[i+1])>>0 === +path[i+1] 
                   ? [] // Yes: assign a new array object
                   : {}, // No: assign a new plain object
         obj)[path[path.length-1]] = value; // Finally assign the value to the last key
    return obj; // Return the top-level object to allow chaining
};

// Demo
var obj = { test: true };
set(obj, "test.1.it", "hello");
console.log(obj); // includes an intentional undefined value

Это немного сложнее, чем get, потому что есть некоторая логика, необходимая для создания отсутствующих частей пути в объекте, для перезаписи примитивных значений, стоящих вспособ и определить, должен ли новый дочерний элемент лучше быть массивом или простым объектом.

...