Как обновить значение во вложенном массиве на основе заданного индекса и вернуть исходный массив в javascript?

#javascript #arrays

Вопрос:

У меня есть индекс «3_1_0» и следующий массив:-

 var fields = [
    {
        name: 'a'
    },
    {
        name: 'b'
    },
    {
        name: 'c'
    },
    {
        name: 'd',
        fields: [
            {
                name: 'd1'
            },
            {
                name: 'd2',
                fields: [
                    {
                        name: 'd2.1'
                    }
                ]
            }
        ]
    }
]
 

Мне нужно извлечь элемент из массива вышеуказанных полей на основе индекса. поэтому 3_1_0 извлечет следующее

 {
    name: 'd2.1'
}
 

Обновите значение с d2.1 до некоторого другого значения, например «new_d2.1», и присоедините обновленное значение к тому же индексу в исходном массиве полей и верните обновленный массив полей. Как это можно сделать?

Ответ №1:

Вы можете использовать Array.reduce для получения желаемого результата. Мы начинаем с разбиения индекса на массив, затем уменьшаем его, чтобы получить результат.

Мы будем использовать некоторые дополнительные цепочки, чтобы гарантировать, что мы вернем undefined , если значение не найдено (скажем, наш индекс был ‘7_10_20’).

Как только мы найдем наш объект, мы сможем задать требуемое свойство.

 const fields = [ { name: 'a' }, { name: 'b' }, { name: 'c' }, { name: 'd', fields: [ { name: 'd1' }, { name: 'd2', fields: [ { name: 'd2.1' } ] } ] } ];

const index = '3_1_0'

function setValue(fields, index, property, value) {
    const obj = index.split('_').reduce((acc, key) => { 
       return acc?.[key] || acc?.fields?.[key];
    }, fields);
    // Only update if we actually find anything
    if (obj) { 
        obj[property] = value
    }
}

setValue(fields, '3_1_0', 'name', 'new_d2.1');

console.log("Fields:", fields); 

Комментарии:

1. Я никогда не замечал arr["0"] , неявно преобразуется как arr[0] .

2. Я считаю, что это фактически одно и то же, нужно было бы взглянуть на спецификацию ECMA. чтобы точно понять, как с этим следует обращаться. Всегда можно сделать .map после разделения, например index.split(‘_’).map(n => n), но я не думаю, что это строго необходимо.

3. Спасибо за ответ, я хочу вернуть исходный массив с именем, обновленным до new_d2.1 в позиции 3_1_0

4. @Терриленнокс, Да. Они-одно и то же, даже происходят в объекте. Я просто никогда не замечал этого раньше.

5. Ценю обратную связь @D. K., которую я обновил!

Ответ №2:

 const data = [{ name: 'a' }, { name: 'b' }, { name: 'c' }, { name: 'd', fields: [ { name: 'd1' }, { name: 'd2', fields: [ { name: 'd2.1' } ] } ] } ];

let givenIdxs = "3_1_0";

let indexes = givenIdxs.split("_");

let result = data[indexes[0]];

for(let idx = 1; idx < indexes.length; idx  ){
  result = result.fields[indexes[idx]];
}

console.log(result);