Javascript. Изменить структуру объекта
Подскажите, как изменить структуру данных с такой
{
"key_1": [
["1", "2"], ["3", "4"], ["5", "6"], ["7", "8"], ["9", "99"]
],
"key_2": [
["10", "20"], ["30", "40"], ["50", "60"], ["70", "80"], ["90", "990"]
]
}
На такую
[
{
"key_1": ["1", "2"],
"key_2": ["10", "20"]
},
{
"key_1": ["3", "4"],
"key_2": ["30", "40"]
},
{
"key_1": ["5", "6"],
"key_2": ["50", "60"]
},
{
"key_1": ["7", "8"],
"key_2": ["70", "80"]
},
{
"key_1": ["9", "99"],
"key_2": ["90", "990"]
}
]
То есть элементы из исходных массивов должны попасть в конечный массив с учётом их индексов: нулевые элементы в нулевой, первые - в первый и так далее. К сожалению, я не очень силён пока что в JS и самостоятельно получилось сделать с помощью этого кода
var final = [];
for (key in temp1) {
temp1[key].reduce((a, current) => {
let b = new Object();
Object.assign(b, {
[key]: current
});
final.push(b);
return a;
}, [])
}
такую структуру, но это не то, что нужно
[
{
"key_1": ["1", "2"]
},
{
"key_1": ["3", "4"]
},
{
"key_1": ["5", "6"]
},
{
"key_1": ["7", "8"]
},
{
"key_1": ["9", "90"]
},
{
"key_2": ["10", "20"]
},
{
"key_2": ["30", "40"]
},
{
"key_2": ["50", "60"]
},
{
"key_2": ["70", "80"]
},
{
"key_2": ["90", "990"]
}
]
Массивы key_1 и key_2 в исходном объекте могут быть разной длины. Оставшиеся элементы(из исходного key_1 или key_2) должны также попасть в конечный массив. Будет просто новый элемент массива такого вида {"key_2": ["90", "990"]} или `{"key_1": ["9", "90"]}
Ответы (2 шт):
В вопросе неправильно был использован метод reduce
- Нужно собирать все в один массив, в данном случае
final, поэтому можно передать его в качестве начального значения, вместо пустого массива - на каждой итерации можно устанавливать элемент массива по конкретному индексу, соответствующему текущему элементу (третий параметр, передаваемый в коллбэк)
- Если по указанному индексу еще нет элемента - установить его
- Если есть, расширить с помощью
Object.assign
В итоге можно получить следующее:
var data = {
"key_1": [
["1", "2"],
["3", "4"],
["5", "6"],
["7", "8"],
["9", "99"]
],
"key_2": [
["10", "20"],
["30", "40"],
["50", "60"],
["70", "80"],
["90", "990"],
["100", "1000"]
]
};
var final = [];
for (key in data) {
final = data[key].reduce((acc, current, index) => {
acc[index] = Object.assign(acc[index] || {}, {
[key]: current
});
return acc;
}, final);
}
console.log(final);
Для любого кол-ва объектов и значений объектов.
- Находим самое длинное значение (массива).
- На основе максимального значения создаём массив-счётчик для перебора.
- Перебирая все ключи заполняем значениями, которые формируются по текущему индексу.
- Если длина какого-то значения (массива) исходного объекта меньше, пропускаем.
const data = {
"key_1": [
["1", "2"],
["3", "4"],
["5", "6"],
["7", "8"],
["9", "99"]
],
"key_2": [
["10", "20"],
["30", "40"],
["50", "60"],
["70", "80"],
["90", "990"]
],
"key_3": [
["100", "200"],
["300", "400"],
["500", "600"]
],
"key_4": [
["146"]
]
};
const maxLength = Math.max(...Object.keys(data).map(item => data[item].length));
const result = [...(Array(maxLength).keys())].reduce((arr, _, index) => {
const current = Object.keys(data).reduce((obj, item) => {
if (index < data[item].length) obj[item] = data[item][index];
return obj;
}, {});
arr.push(current);
return arr;
}, []);
console.log(result);
При необходимости можно загнать в одну строку.
const data = {
"key_1": [
["1", "2"],
["3", "4"],
["5", "6"],
["7", "8"],
["9", "99"]
],
"key_2": [
["10", "20"],
["30", "40"],
["50", "60"],
["70", "80"],
["90", "990"]
],
"key_3": [
["100", "200"],
["300", "400"],
["500", "600"]
],
"key_4": [
["146"]
]
};
const result = [...(Array(Math.max(...Object.keys(data).map(item => data[item].length))).keys())].reduce((arr, _, index) => (_ = Object.keys(data).reduce((obj, item) => (index < data[item].length && (obj[item] = data[item][index]), obj), {}), arr.push(_), arr), []);
console.log(result);