#javascript
#javascript
Вопрос:
У меня ниже ответа API необходимо создать уникальный массив объекта на основе идентификатора.
const response = [{id: "ABC", value: 120, day: "MON"},{id: "ABC", value: 120, day: "TUE"},{id: "ABC", value: 120, day: "WED"},{id: "ABC", value: 120, day: "THU"},{id: "ABC", value: 120, day: "FRI"},
{id: "XYZ", value: 120, day: "TUE"},{id: "XYZ", value: 140, day: "WED"},{id: "XYZ", value: 160, day: "FRI"},{id: "SUV", value: 120, day: "MON"},{id: "SUV", value: 140, day: "TUE"}];
Я хочу уникальный массив объекта, как показано ниже
obj = [{ItemID: "ABC", MON: 120, TUE: 120, WED: 120, THU: 120, FRI: 120 }, {ItemID: "XYZ", TUE: 120, WED: 140, FRI: 160 }, {ItemID: "SUV", MON: 120, TUE: 140} ];
Я попробовал следующий метод
let obj = {ItemID: ""};
let arr = [];
response.forEach(el => {
let day = el.day;
obj.ItemID = el.id;
obj[day] = el.value
}
)
arr.push(obj);
console.log(arr)
Используя приведенный выше код, я всегда получаю ниже массива объекта. Я не могу добавить другой объект, когда идентификатор не соответствует
obj = [{ItemID: "ABC", MON: 120, TUE: 120, WED: 120, THU: 120, FRI: 120 }]
Ответ №1:
Вы можете использовать Array.reduce
наряду с Object.values
.
const response = [{id: "ABC", value: 120, day: "MON"},{id: "ABC", value: 120, day: "TUE"},{id: "ABC", value: 120, day: "WED"},{id: "ABC", value: 120, day: "THU"},{id: "ABC", value: 120, day: "FRI"},
{id: "XYZ", value: 120, day: "TUE"},{id: "XYZ", value: 140, day: "WED"},{id: "XYZ", value: 160, day: "FRI"},{id: "SUV", value: 120, day: "MON"},{id: "SUV", value: 140, day: "TUE"}];
const formatResponse = (data) => {
const finalRes = data.reduce((res, {id, value, day}) => {
res[id] = {
ItemID: id,
...res[id],
[day]: value
}
return res;
},{});
return Object.values(finalRes)
}
console.log(formatResponse(response))
.as-console-wrapper {
max-height: 100% !important;
}
Использование Array.forEach
также может быть достигнуто, но затем reduce
становится более информативным, когда мы смотрим на метод, что мы выполняем какую-то обработку и накапливаем предоставленные данные на основе идентификатора.
const response = [{id: "ABC", value: 120, day: "MON"},{id: "ABC", value: 120, day: "TUE"},{id: "ABC", value: 120, day: "WED"},{id: "ABC", value: 120, day: "THU"},{id: "ABC", value: 120, day: "FRI"},
{id: "XYZ", value: 120, day: "TUE"},{id: "XYZ", value: 140, day: "WED"},{id: "XYZ", value: 160, day: "FRI"},{id: "SUV", value: 120, day: "MON"},{id: "SUV", value: 140, day: "TUE"}];
const processResponse = (data) => {
const finalRes = {};
data.forEach(({id, value, day}) => {
finalRes[id] = {
ItemID: id,
...finalRes[id],
[day]: value
}
});
return Object.values(finalRes)
}
console.log(processResponse(response));
.as-console-wrapper {
max-height: 100% !important;
}
Комментарии:
1. Спасибо, что поделились каждым способом. Это решает мою единственную проблему. Мне нужно отформатировать день, прежде чем переходить к использованию moment, чего не происходит из-за метода reduce. Но это работа с forEach
Ответ №2:
Вы можете использовать Array.prototype.reduce
для накопления объектов в массиве и Array.prototype.find
для поиска существующего объекта с определенным ItemID
в массиве.
Если найдено, измените объект с помощью новых данных, иначе добавьте новый новый объект:
const response = [{id: "ABC", value: 120, day: "MON"},{id: "ABC", value: 120, day: "TUE"},{id: "ABC", value: 120, day: "WED"},{id: "ABC", value: 120, day: "THU"},{id: "ABC", value: 120, day: "FRI"},
{id: "XYZ", value: 120, day: "TUE"},{id: "XYZ", value: 140, day: "WED"},{id: "XYZ", value: 160, day: "FRI"},{id: "SUV", value: 120, day: "MON"},{id: "SUV", value: 140, day: "TUE"}];
const processObject = (res) => {
return res.reduce((acc, o) => {
let day = acc.find(d => d.ItemID === o.id);
if (day) {
day[o.day] = o.value;
} else {
acc.push({
ItemID: o.id,
[o.day]: o.value
});
}
return acc;
}, [])
}
console.log(processObject(response));
В вашем коде вы всегда переопределяете один и тот же объект, вы должны создать новый объект, когда ItemID
он изменился. если это то же ItemID
самое, вы должны выполнить его поиск и изменить результат или создать новый и вставить в конечный массив.
Комментарии:
1. Можем ли мы достичь только через forEach?