我有这样的数据:
const data = [
{ id: 1, cat: "human", age: "10" },
{ id: 2, cat: "human", age: "20" },
{ id: 3, cat: "human", age: "10" },
{ id: 4, cat: "animal", age: "10" },
{ id: 5, cat: "animal", age: "20" },
{ id: 6, cat: "animal", age: "10" },
{ id: 7, cat: "alien", age: "10" },
{ id: 8, cat: "alien", age: "20" },
{ id: 9, cat: "alien", age: "10" },
];
我想像这样对数据进行分组:
const gr = {
human: {
all: [
{ id: 1, cat: "human", age: "10" },
{ id: 2, cat: "human", age: "20" },
{ id: 3, cat: "human", age: "10" },
],
ages: {
"10": [
{ id: 1, cat: "human", age: "10" },
{ id: 3, cat: "human", age: "10" },
],
"20": [
{ id: 2, cat: "human", age: "20" },
],
}
},
animal: {...},
alien: {...},
}
我首先要这样减少:
const gr = data.reduce((acc, el) => {
const { cat } = el;
acc[cat] = acc[cat] || { all: [] };
acc[cat].all.push(el);
return acc;
}, {});
但是我不能在这里做嵌套的减少。我可以这样单独做:
const grAge = gr.human.all.reduce((acc,el) => {
const {age} = el;
acc[age] = acc[age] || [];
acc[age].push(el);
return acc;
},{});
gr.human["ages"] = grAge;
但是显然,这不是那么有效,需要更多的工作。也许像这样:
Object.keys(gr).forEach(key => {
const grAge = gr[key].all.reduce((acc,el) => {
const {age} = el;
acc[age] = acc[age] || [];
acc[age].push(el);
return acc;
},{});
gr[key]["ages"] = grAge;
});
我可以一步一步加入这些减法吗?
如果我可以使用其他任何好的方法,则不需要使用reduce方法。
答案 0 :(得分:3)
您可以采用单循环方法,将所需的结构分配给all
或嵌套结构。
如果您希望获得更动态的版本,则需要简化每个嵌套级别的结果结构(这意味着年龄级别将包含all
属性)。
const
data = [{ id: 1, cat: "human", age: "10" }, { id: 2, cat: "human", age: "20" }, { id: 3, cat: "human", age: "10" }, { id: 4, cat: "animal", age: "10" }, { id: 5, cat: "animal", age: "20" }, { id: 6, cat: "animal", age: "10" }, { id: 7, cat: "alien", age: "10" }, { id: 8, cat: "alien", age: "20" }, { id: 9, cat: "alien", age: "10" }],
result = data.reduce((r, o) => {
r[o.cat] = r[o.cat] || { all: [], ages: {} };
r[o.cat].all.push(o);
r[o.cat].ages[o.age] = r[o.cat].ages[o.age] || [];
r[o.cat].ages[o.age].push(o);
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
另一种方法是使用Sets获取每个唯一的类别和年龄,然后将其简化为最终的JSON:
编辑:似乎Stack Overflow片段不喜欢它,但是在浏览器控制台中执行它会给出正确的结果
const data = [
{ id: 1, cat: "human", age: "10" },
{ id: 2, cat: "human", age: "20" },
{ id: 3, cat: "human", age: "10" },
{ id: 4, cat: "animal", age: "10" },
{ id: 5, cat: "animal", age: "20" },
{ id: 6, cat: "animal", age: "10" },
{ id: 7, cat: "alien", age: "10" },
{ id: 8, cat: "alien", age: "20" },
{ id: 9, cat: "alien", age: "10" },
];
const output = [...new Set(data.map(thing => thing.cat))].reduce((acc, category) => {
const catData = data.filter(thing => thing.cat === category)
return {
[category]: {
all: catData,
ages : [...new Set(catData.map(catThing => catThing.age))].reduce((catAcc, age) => ({
[age]: [...catData.filter(catThing => catThing.age === age)],
...catAcc
}), {})
},
...acc
}
}, {})
console.log(output)
.as-console-wrapper { max-height: 100% !important; top: 0; }