#javascript #javascript-objects
Вопрос:
const object = {
key1: 'example_key1',
key2: {
key3: 'example_key2'
}
}
const string = 'key1'
const array = ['key2', 'key3']
object[string] = 'foo' // Work
object[array] = 'bar' // Dont work
Как я могу получить доступ к объекту и изменить его с помощью массива ключей?
Я пробовал loadash.get
, но он может только получать значения, а не изменять их.
Комментарии:
1. Что вы ожидаете
object[array]
вернуть?2. Объект[индекс] — это то, что вам нужно, поэтому, если вы дадите объект[массив[0]], это сработает. Но если вы хотите, чтобы все значения, которые вам нужны, были инициализированы в bar, тогда это отдельная история
3. Будет ли массив всегда иметь длину 2 или он может быть длиннее ?
4. Да, массив может измениться. И быть длиннее или короче.
Ответ №1:
Вам нужно сделать что-то вроде следующего:
function set(obj, path, value) {
var schema = obj
var len = path.length
for(var i = 0; i < len - 1; i ) {
var elem = path[i]
if (!schema[elem] ) schema[elem] = {}
schema = schema[elem]
}
schema[path[len-1]] = value
}
И тогда вы могли бы использовать его следующим образом:
set(object, array, 'someText')
С помощью функции, подобной описанной выше set
, вы можете обновить объект, передав массив вложенных ключей и новое значение.
Ответ №2:
Вы могли бы сделать что-то вроде:
const object = {
key1: 'example_key1',
key2: {
key3: 'example_key2'
}
}
const string = 'key1'
const array = ['key2', 'key3']
console.log(object[array[0]][array[1]])
Редактировать
Первое решение-статическое. Приведенное ниже решение является более динамичным:
const object = {
key1: 'example_key1',
key2: {
key3: 'example_key2'
}
}
const object2 = {
key1: 'example_key1',
key2: {
key3: {
key4: "example_key3"
}
}
}
const string = 'key1'
const array = ['key2', 'key3']
let nestedObj = undefined;
array.forEach(val => {
if (nestedObj) nestedObj = nestedObj[val];
else nestedObj = object[val];
})
console.log(nestedObj)
const array2 = ['key2', 'key3', 'key4']
let nestedObj2 = undefined;
array2.forEach(val => {
if (nestedObj2) nestedObj2 = nestedObj2[val];
else nestedObj2 = object2[val];
})
console.log(nestedObj2)
Комментарии:
1. что это ты здесь делаешь?
2. Это работает, но если я изменю массив, мне нужно будет добавить его вручную
array[2]
.3. @PowerKuu Я добавил динамическое решение к своему ответу =)
Ответ №3:
Вы можете создать рекурсивную функцию и проверить, существует ли ключ от объекта в массиве, если да, то измените значение ключа в объекте
const object = {
key1: 'example_key1',
key2: {
key3: 'example_key2'
},
key3: 'someVal'
}
const array = ['key2', 'key3']
function doRecursion(obj) {
for (let keys in obj) {
if (array.includes(keys)) {
console.log(typeof obj[keys])
if (typeof obj[keys] === 'object') {
doRecursion(obj[keys])
} else {
obj[keys] = 'bar';
}
} else {
console.log(keys)
}
}
return obj
};
console.log(doRecursion(object));
Ответ №4:
Я думаю, что здесь рекурсия облегчит задачу
function get(obj, keys) {
if(typeof keys === 'string') {
return obj[keys];
}
const key = keys.shift();
return keys.length ? get(obj[key], keys) : obj[key];
}
const object1 = {
key1: 'example_key1',
key2: {
key3: 'example_key2'
}
}
const object2 = {
key1: 'example_key1',
key2: {
key3: {
key4: "example_key3"
}
}
}
const string = 'key1'
const array1 = ['key2', 'key3'];
const array2 = ['key2', 'key3', 'key4'];
console.log(get(object1, string));
console.log(get(object1, array1));
console.log(get(object2, array2));