使用 d3.groups 按多个键对对象数组进行分组
Group array of objects by multiple keys using d3.groups
我有这个数据集:
const data = [
{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1},
{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0},
{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1},
{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0},
{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0},
{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
{animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1},
]
我想按 animal
和 status
对它进行分组以获得如下内容:
const grouped = {
cat: {
-1: [{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1}],
0: [{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0}]
1: [{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1}]
},
dog: {
0: [{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0}],
1: [
{animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1}
]
},
hamster: {
0: [{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0}],
},
't-rex': {
0: [{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
{animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},],
},
sheep: {
-1: [{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1}],
0: [{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0}],
}
}
我用d3.groups
对数据进行分组:
const grouped = d3.groups(data, d => d.animal, d => d.status)
/*
[
[
'cat',
[
[
-1,
[
{
animal: 'cat',
name: 'mu',
date: 2019-12-31T23:00:00.000Z,
status: -1
}
]
],
[
0,
[
{
animal: 'cat',
name: 'muji',
date: 2020-12-31T23:00:00.000Z,
status: 0
}
]
],
[
1,
[
{
animal: 'cat',
name: 'mine',
date: 2020-12-31T23:00:00.000Z,
status: 1
}
]
]
]
],
[
'dog',
[
[
1,
[
{
animal: 'dog',
name: 'fido',
date: 2020-12-31T23:00:00.000Z,
status: 1
},
{
animal: 'dog',
name: 'fido2',
date: 2019-12-31T23:00:00.000Z,
status: 1
}
]
],
[
0,
[
{
animal: 'dog',
name: 'fido3',
date: 2020-12-31T23:00:00.000Z,
status: 0
}
]
]
]
],
[
'hamster',
[
[
0,
[
{
animal: 'hamster',
name: 'gerry',
date: 2018-12-31T23:00:00.000Z,
status: 0
}
]
]
]
],
[
't-rex',
[
[
0,
[
{
animal: 't-rex',
name: 'dino',
date: 2019-12-31T23:00:00.000Z,
status: 0
},
{
animal: 't-rex',
name: 'sauro',
date: 2018-12-31T23:00:00.000Z,
status: 0
}
]
]
]
],
[
'sheep',
[
[
0,
[
{
animal: 'sheep',
name: 's',
date: 2018-12-31T23:00:00.000Z,
status: 0
}
]
],
[
-1,
[
{
animal: 'sheep',
name: 'sss',
date: 2018-12-31T23:00:00.000Z,
status: -1
}
]
]
]
]
]
*/
分组正常,但数据不是我需要的格式。
您可以在 d3.groups
之后链接一个 .reduce
,以便将嵌套数组重新转换为嵌套对象。
您可以使用 {}
初始化 reduce
,因此它 returns 是一个对象。 curr[0]
从 d3.groups
返回的每个数组将是 animal
。对于从 d3.groups
返回的每个数组,curr[1]
将是 status
的数组和按 animal
/ status
逻辑分组的原始项目数组。
见下文:
const data = [
{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1},
{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0},
{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1},
{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0},
{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0},
{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
{animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1},
];
const grouped = d3.groups(
data,
d => d.animal,
d => d.status
).reduce((acc, curr) => {
let obj = {};
curr[1].forEach(item => obj[item[0]] = item[1]);
acc[curr[0]] = obj;
return acc;
}, {});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>
我有这个数据集:
const data = [
{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1},
{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0},
{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1},
{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0},
{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0},
{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
{animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1},
]
我想按 animal
和 status
对它进行分组以获得如下内容:
const grouped = {
cat: {
-1: [{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1}],
0: [{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0}]
1: [{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1}]
},
dog: {
0: [{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0}],
1: [
{animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1}
]
},
hamster: {
0: [{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0}],
},
't-rex': {
0: [{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
{animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},],
},
sheep: {
-1: [{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1}],
0: [{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0}],
}
}
我用d3.groups
对数据进行分组:
const grouped = d3.groups(data, d => d.animal, d => d.status)
/*
[
[
'cat',
[
[
-1,
[
{
animal: 'cat',
name: 'mu',
date: 2019-12-31T23:00:00.000Z,
status: -1
}
]
],
[
0,
[
{
animal: 'cat',
name: 'muji',
date: 2020-12-31T23:00:00.000Z,
status: 0
}
]
],
[
1,
[
{
animal: 'cat',
name: 'mine',
date: 2020-12-31T23:00:00.000Z,
status: 1
}
]
]
]
],
[
'dog',
[
[
1,
[
{
animal: 'dog',
name: 'fido',
date: 2020-12-31T23:00:00.000Z,
status: 1
},
{
animal: 'dog',
name: 'fido2',
date: 2019-12-31T23:00:00.000Z,
status: 1
}
]
],
[
0,
[
{
animal: 'dog',
name: 'fido3',
date: 2020-12-31T23:00:00.000Z,
status: 0
}
]
]
]
],
[
'hamster',
[
[
0,
[
{
animal: 'hamster',
name: 'gerry',
date: 2018-12-31T23:00:00.000Z,
status: 0
}
]
]
]
],
[
't-rex',
[
[
0,
[
{
animal: 't-rex',
name: 'dino',
date: 2019-12-31T23:00:00.000Z,
status: 0
},
{
animal: 't-rex',
name: 'sauro',
date: 2018-12-31T23:00:00.000Z,
status: 0
}
]
]
]
],
[
'sheep',
[
[
0,
[
{
animal: 'sheep',
name: 's',
date: 2018-12-31T23:00:00.000Z,
status: 0
}
]
],
[
-1,
[
{
animal: 'sheep',
name: 'sss',
date: 2018-12-31T23:00:00.000Z,
status: -1
}
]
]
]
]
]
*/
分组正常,但数据不是我需要的格式。
您可以在 d3.groups
之后链接一个 .reduce
,以便将嵌套数组重新转换为嵌套对象。
您可以使用 {}
初始化 reduce
,因此它 returns 是一个对象。 curr[0]
从 d3.groups
返回的每个数组将是 animal
。对于从 d3.groups
返回的每个数组,curr[1]
将是 status
的数组和按 animal
/ status
逻辑分组的原始项目数组。
见下文:
const data = [
{animal: 'cat', name: 'mu', date: new Date(2020, 0, 1), status: -1},
{animal: 'cat', name: 'muji', date: new Date(2021, 0, 1), status: 0},
{animal: 'cat', name: 'mine', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido', date: new Date(2021, 0, 1), status: 1},
{animal: 'dog', name: 'fido2', date: new Date(2020, 0, 1), status: 1},
{animal: 'dog', name: 'fido3', date: new Date(2021, 0, 1), status: 0},
{animal: 'hamster', name: 'gerry', date: new Date(2019, 0, 1), status: 0},
{animal: 't-rex', name: 'dino', date: new Date(2020, 0, 1), status: 0},
{animal: 't-rex', name: 'sauro', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 's', date: new Date(2019, 0, 1), status: 0},
{animal: 'sheep', name: 'sss', date: new Date(2019, 0, 1), status: -1},
];
const grouped = d3.groups(
data,
d => d.animal,
d => d.status
).reduce((acc, curr) => {
let obj = {};
curr[1].forEach(item => obj[item[0]] = item[1]);
acc[curr[0]] = obj;
return acc;
}, {});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>