#javascript #arrays #object
#javascript #массивы #объект
Вопрос:
У меня есть данные массива, и после итерации я хочу получить новый массив с другой структурой
Это мой исходный массив:
let oldArr = [
{
"20200714": [
{
"StartDate": "2020-07-14T11:05:31.151687000",
"EndDate": "2020-07-14T12:11:59.673687000",
},
{
"StartDate": "2020-07-14T13:05:31.151687000",
"EndDate": "2020-07-14T14:11:59.673687000",
},
],
"20200715": [
{
"StartDate": "2020-07-15T14:05:31.151687000",
"EndDate": "2020-07-15T15:11:59.673687000",
}
]
}
]
Вывод должен быть таким:
[
{
x: '20200714',
y: [
'2020-07-14T11:05:31.151687000',
'2020-07-14T12:11:59.673687000',
]
},
{
x: '20200714',
y: [
'2020-07-14T13:05:31.151687000',
'2020-07-14T13:05:31.151687000',
]
},
{
x: '20200715',
y: [
'2020-07-15T14:05:31.151687000',
'2020-07-15T15:11:59.673687000',
]
}
]
Я пытаюсь выполнить итерацию массива с помощью map () что-то вроде этого, но я не знаю, как это сделать правильно
let newArr = oldArr.map((key) => {
return {
x: key,
y: [
key.StartDate,
key.EndDate
]
}
)
Заранее спасибо
Ответ №1:
Вам нужно объединить несколько редукторов для доступа к нужным данным:
let oldArr = [
{
"20200714": [
{
"StartDate": "2020-07-14T11:05:31.151687000",
"EndDate": "2020-07-14T12:11:59.673687000",
},
{
"StartDate": "2020-07-14T13:05:31.151687000",
"EndDate": "2020-07-14T14:11:59.673687000",
},
],
"20200715": [
{
"StartDate": "2020-07-15T14:05:31.151687000",
"EndDate": "2020-07-15T15:11:59.673687000",
}
]
}
]
const newArr = oldArr.reduce((mainAcc, currItem) => [...mainAcc, ...Object.keys(currItem).reduce((acc, currKey) => {
const vals = currItem[currKey];
return [
...acc,
vals.map((v) => ({ x: currKey, y: [v.StartDate, v.EndDate] })),
];
}, [])], []);
console.log(newArr);
Комментарии:
1. Решение от Люка Сторри легче читать и потребует лишь небольшой адаптации, чтобы заставить его работать для всего массива. Решение, которое я опубликовал, работает с массивом как oldArr и будет учитывать каждый элемент массива. Вы должны пойти и попытаться реализовать что-нибудь на основе этого кода.
Ответ №2:
Ваш источник на самом деле представляет собой массив из одного объекта, поэтому вы хотите использовать Object.entries
для получения массива, а затем выполнить цикл над этими записями с помощью вложенного цикла над внутренним массивом y
значений.
Из-за трех вложенных циклов код упрощается, если вы просто создаете массив и нажимаете на него в forEach
, а не вкладываете несколько reduce
циклов:
let oldArr = [{
"20200714": [{
"StartDate": "2020-07-14T11:05:31.151687000",
"EndDate": "2020-07-14T12:11:59.673687000",
},
{
"StartDate": "2020-07-14T13:05:31.151687000",
"EndDate": "2020-07-14T14:11:59.673687000",
},
],
"20200715": [{
"StartDate": "2020-07-15T14:05:31.151687000",
"EndDate": "2020-07-15T15:11:59.673687000",
}]
}]
let newArr = []
oldArr.forEach(outerObject => Object.entries(outerObject)
.forEach(([key, items]) =>
items.forEach((item) => newArr.push({
x: key,
y: [item.StartDate, item.EndDate]
}))
)
)
console.log(newArr)
Комментарии:
1. зачем ограничиваться первым индексом? если это массив, то наверняка в нем есть другие элементы
2. Не «наверняка» — я использовал фрагмент кода из примера данных — третий вложенный цикл может не понадобиться.
3. если не более 1 элемента, ваш 3-й цикл не увеличит временную сложность, верно? Но если имеется более 1 элемента, ваше решение завершится неудачей
4. Дело не во временной сложности. У вас есть входные данные, вы хотите получить выходные. Входные данные могут содержать больше записей во внешнем массиве, а могут и нет — добавление другого вложенного редуктора для создания беспорядочной трехуровневой вложенности добавляет ненужную сложность коду, обычно лучше упростить его. Тем не менее, я обновил код, чтобы добавить дополнительную вложенность, но чтобы он выглядел проще, я изменил на
forEach
вместоreduce
Ответ №3:
Вы можете выполнить обычный for
цикл для перебора ключей объекта. На самом деле это довольно просто:
var obj = [{
"20200714": [{
"StartDate": "2020-07-14T11:05:31.151687000",
"EndDate": "2020-07-14T12:11:59.673687000",
},
{
"StartDate": "2020-07-14T13:05:31.151687000",
"EndDate": "2020-07-14T14:11:59.673687000",
},
],
"20200715": [{
"StartDate": "2020-07-15T14:05:31.151687000",
"EndDate": "2020-07-15T15:11:59.673687000",
}]
}];
var newObj = [];
for (var i = 0; i < obj.length; i ) {
var currentKeys = Object.keys(obj[i]);
for (var j = 0; j < currentKeys.length; j ) {
for (var k = 0; k < obj[i][currentKeys[j]].length; k ) {
newObj.push({
x: currentKeys[j],
y: [obj[i][currentKeys[j]][k].StartDate, obj[i][currentKeys[j]][k].EndDate]
});
}
}
}
newObj
значение:
[
{
"x": "20200714",
"y": [
"2020-07-14T11:05:31.151687000",
"2020-07-14T12:11:59.673687000"
]
},
{
"x": "20200714",
"y": [
"2020-07-14T13:05:31.151687000",
"2020-07-14T14:11:59.673687000"
]
},
{
"x": "20200715",
"y": [
"2020-07-15T14:05:31.151687000",
"2020-07-15T15:11:59.673687000"
]
}
]
Ответ №4:
я думаю, проблема в том, что у вас есть массив с одним объектом внутри. Итак, когда вы используете карту массива, ваш «ключ» — это позиция 0 массива, я думаю, вы можете сделать что-то подобное, чтобы получить ожидаемый результат:
Object.keys(oldArr).reduce((acc, current) => {
console.log(acc, current)
oldArr[current].forEach((objWithDate) => {
acc.push({
x: current,
y: [objWithDate.StartDate, objWithDate.EndDate]
})
})
return acc
}, [])
я действительно не знаю вашу версию node или если это для Интернета, но я надеюсь, что это сработает для вас. хорошего дня