#javascript #arrays #object #grouping
#javascript #массивы #объект #группировка
Вопрос:
Я пытаюсь найти способ преобразовать этот список объектов на основе массива group. Сложная часть, которую я обнаружил, заключается в переборе массива групп и применении объекта к нескольким местам, если существует несколько групп.
Я также пытаюсь игнорировать любую группу, которая ни к чему не принадлежит. Я пытался использовать функцию reduce, но я не могу получить итерацию через массив group.
let cars =
[
{
"group":[],
"name": "All Makes",
"code": ""
},
{
"group":["Group A"],
"name": "BMW",
"code": "X821"
},
{
"group":["Group B"],
"name": "Audi",
"code": "B216"
},
{
"group":["Group B"],
"name": "Ford",
"code": "P385"
},
{
"group":["Group B", "Group C"],
"name": "Mercedes",
"code": "H801"
},
{
"group":["Group C"],
"name": "Honda",
"code": "C213"
}
]
Чтобы стать этим:
[
{
"group": "Group A",
"cars": [
{
name: "BMW",
code: "X821"
}
]
},
{
"group": "Group B",
"cars": [
{
name: "Audi",
code: "B216"
},
{
name: "Ford",
code: "P385"
},
{
name: "Mercedes",
code: "H801"
}
]
},
{
"group": "Group C",
"cars": [
{
name: "Mercedes",
code: "H801"
},
{
name: "Honda",
code: "C213"
}
]
}
]
Я уже пробовал использовать reduce для достижения этой цели, но это не совсем дает желаемый эффект.
const res = cars.reduce((acc, {group, ...r}) => {
group.forEach(key => {
acc[key] = (acc[key] || []).concat({...r});
});
return acc;
}, []);
console.log(res);
Ответ №1:
Использование строковых ключей в массивах работает не совсем хорошо, для этого и нужны объекты, затем используйте Object.values
, чтобы извлечь из него массив. Также вы хотите поместить туда объекты, а не массивы:
const res = Object.values(cars.reduce((acc, {group, ...r}) => {
group.forEach(key => {
(acc[key] = (acc[key] || { group, cars: [] })).cars.push(r);
});
return acc;
}, {}));
Я бы написал это так:
const byGroup = new Map();
for(const { group, ...rest } of cars) {
if(!byGroup.has(group))
byGroup.set(group, { group, cars: [] });
byGroup.get(group).cars.push(rest);
}
const result = [...byGroup.values()];
Ответ №2:
Вам нужно взять объект в качестве накопителя, а затем сопоставить записи для получения желаемого результата.
let cars = [{ group: [], name: "All Makes", code: "" }, { group: ["Group A"], name: "BMW", code: "X821" }, { group: ["Group B"], name: "Audi", code: "B216" }, { group: ["Group B"], name: "Ford", code: "P385" }, { group: ["Group B", "Group C"], name: "Mercedes", code: "H801" }, { group: ["Group C"], name: "Honda", code: "C213" }],
result = Object
.entries(cars.reduce((acc, { group, ...r }) => {
group.forEach(key => acc[key] = (acc[key] || []).concat({...r}));
return acc;
}, {}))
.map(([group, cars]) => ({ group, cars }));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }