如何对 javascript 对象进行分组?
How to group an javascript object?
我有一个来自数据库输入的 javascript 数组对象,如下所示:
[{ date: '2021-09-15', type: 'cats', value: 4 },
{ date: '2021-09-15', type: 'dogs', value: 5 },
{ date: '2021-09-16', type: 'cats', value: 1 },
{ date: '2021-09-16', type: 'dogs', value: 4 }]
我需要这样的输出:
[{ date: '2021-09-15', cats: 4, dogs: 5 },
{ date: '2021-09-16', cats: 1, dogs: 4 }]
我正在尝试通过这种方式使用 reduce 函数,但是,我无法让它工作(它对数据进行分组但不修改它,因此它们只剩下一个值)
const data = [
{ date: '2021-09-15', type: 'cats', value: 4 },
{ date: '2021-09-15', type: 'dogs', value: 5 },
{ date: '2021-09-16', type: 'cats', value: 1 },
{ date: '2021-09-16', type: 'dogs', value: 4 }
]
const groups = data.reduce((groups, item) => {
const key = item[item.date];
if (!groups[key]) {
groups[item.date] = []
}
if (item.type == "cats") {
item.cats = item.value;
} else if (item.type == "dogs") {
item.dogs = item.value;
}
groups[item.date].push(item);
return groups;
}, {});
console.log(groups)
.as-console-wrapper { max-height: 100% !important; }
如果第二个对象具有相同 date
并且已经存在 type
。这也涵盖了您有多个具有相同 type
的对象的情况,然后它将加起来 value
const arr = [
{ date: "2021-09-15", type: "cats", value: 4 },
{ date: "2021-09-15", type: "cats", value: 5 },
{ date: "2021-09-16", type: "cats", value: 1 },
{ date: "2021-09-16", type: "dogs", value: 4 },
];
const map = new Map();
arr.forEach((o) => {
const { date, type, value } = o;
if (!map.has(date)) map.set(o.date, { date, [type]: value });
else {
const target = map.get(date);
const { type: newType, value: newValue } = o;
target[newType] = target[newType] ? target[newType] + newValue : newValue;
}
});
const result = [...map.values()];
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
这真的是一个两步过程...
- 将按
date
分组的数据收集到地图中
- 将最终结果转化为你想要的数组
const data = [{"date":"2021-09-15","type":"cats","value":4},{"date":"2021-09-15","type":"dogs","value":5},{"date":"2021-09-16","type":"cats","value":1},{"date":"2021-09-16","type":"dogs","value":4}]
const t1 = performance.now()
const mapped = data.reduce((map, { date, type, value }) => {
// get the current entry for date, default to `{}`
const obj = map.get(date) ?? {}
// merge and set the new entry
return map.set(date, {
...obj,
[ type ]: (obj[type] ?? 0) + value
})
}, new Map())
const groups = Array.from(mapped, ([ date, obj ]) => ({
date,
...obj
}))
const t2 = performance.now()
console.log(groups, `\nTook ${t2 - t1}ms`)
.as-console-wrapper { max-height: 100% !important; }
你的问题并不清楚,但这个答案总结了同一日期的所有相同类型的值。
我有一个来自数据库输入的 javascript 数组对象,如下所示:
[{ date: '2021-09-15', type: 'cats', value: 4 },
{ date: '2021-09-15', type: 'dogs', value: 5 },
{ date: '2021-09-16', type: 'cats', value: 1 },
{ date: '2021-09-16', type: 'dogs', value: 4 }]
我需要这样的输出:
[{ date: '2021-09-15', cats: 4, dogs: 5 },
{ date: '2021-09-16', cats: 1, dogs: 4 }]
我正在尝试通过这种方式使用 reduce 函数,但是,我无法让它工作(它对数据进行分组但不修改它,因此它们只剩下一个值)
const data = [
{ date: '2021-09-15', type: 'cats', value: 4 },
{ date: '2021-09-15', type: 'dogs', value: 5 },
{ date: '2021-09-16', type: 'cats', value: 1 },
{ date: '2021-09-16', type: 'dogs', value: 4 }
]
const groups = data.reduce((groups, item) => {
const key = item[item.date];
if (!groups[key]) {
groups[item.date] = []
}
if (item.type == "cats") {
item.cats = item.value;
} else if (item.type == "dogs") {
item.dogs = item.value;
}
groups[item.date].push(item);
return groups;
}, {});
console.log(groups)
.as-console-wrapper { max-height: 100% !important; }
如果第二个对象具有相同 date
并且已经存在 type
。这也涵盖了您有多个具有相同 type
的对象的情况,然后它将加起来 value
const arr = [
{ date: "2021-09-15", type: "cats", value: 4 },
{ date: "2021-09-15", type: "cats", value: 5 },
{ date: "2021-09-16", type: "cats", value: 1 },
{ date: "2021-09-16", type: "dogs", value: 4 },
];
const map = new Map();
arr.forEach((o) => {
const { date, type, value } = o;
if (!map.has(date)) map.set(o.date, { date, [type]: value });
else {
const target = map.get(date);
const { type: newType, value: newValue } = o;
target[newType] = target[newType] ? target[newType] + newValue : newValue;
}
});
const result = [...map.values()];
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
这真的是一个两步过程...
- 将按
date
分组的数据收集到地图中 - 将最终结果转化为你想要的数组
const data = [{"date":"2021-09-15","type":"cats","value":4},{"date":"2021-09-15","type":"dogs","value":5},{"date":"2021-09-16","type":"cats","value":1},{"date":"2021-09-16","type":"dogs","value":4}]
const t1 = performance.now()
const mapped = data.reduce((map, { date, type, value }) => {
// get the current entry for date, default to `{}`
const obj = map.get(date) ?? {}
// merge and set the new entry
return map.set(date, {
...obj,
[ type ]: (obj[type] ?? 0) + value
})
}, new Map())
const groups = Array.from(mapped, ([ date, obj ]) => ({
date,
...obj
}))
const t2 = performance.now()
console.log(groups, `\nTook ${t2 - t1}ms`)
.as-console-wrapper { max-height: 100% !important; }
你的问题并不清楚,但这个答案总结了同一日期的所有相同类型的值。