Reputation: 438
I've this dataset:
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},
]
And I want to group it by animal
and by status
to obtain something like:
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}],
}
}
I used d3.groups
to groups data:
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
}
]
]
]
]
]
*/
the grouping is working but data is not in the format I need.
Upvotes: 1
Views: 788
Reputation: 19289
You can chain a .reduce
after d3.groups
in order that the nested array is recast into a nested object.
You can initialize the reduce
with {}
so it returns an object. curr[0]
for each array returned from d3.groups
will be the animal
. curr[1]
for each array returned from d3.groups
will be the array of the status
and the original array of items grouped per the animal
/ status
logic.
See below:
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>
Upvotes: 2