I found a clear answer on how to group using reduce.
Most efficient method to groupby on an array of objects
const array = [
{ _id:" 5fbcca92c36b24d99395623d",
assetData:
{ _id: "5fbcca159ae5f2d8ed792542",
name: 'House 1',
numberOfRooms: '1',
numberOfBathrooms: '2' } },
{ _id: "5fbcca92c36b24d99395623c",
assetData:
{ _id: "5fbcca159ae5f2d8ed792542",
name: 'House 1',
numberOfRooms: '1',
numberOfBathrooms: '2' } },
{ _id: "5fbccb32c36b24d993956242",
assetData:
{ _id: "5fbbedcb4decb58513e4ba80",
name: 'House 2',
numberOfRooms: '1',
numberOfBathrooms: '1' } },
{ _id: "5fbccb32c36b24d993956243",
assetData:
{ _id: "5fbbedcb4decb58513e4ba80",
name: 'House 2',
numberOfRooms: '1',
numberOfBathrooms: '1' } },
];
const groupBy = function (xs, key) {
return xs.reduce(function (rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
const test = Object.entries(groupBy(array, "_id"));
console.log(test);
I'm trying to adapt to, instead of sorting by the _id
, sort by assetData._id
. Changing the key
argument on the groupBy
function, do not the output's behavior. It does not accept the value of a subdocument. I don't know even how to proceed with my research because I couldn't really understand what this part of the function (rv[x[key]] = rv[x[key]] || [])
means. I started reading something about metaprogramming in ES6, but I'm not sure if it will lead me to an answer. Any tip?
Well, since I have no theoretical response yet, I tried to solve the problem in a practical way. It seems that I can't pass the string assetData._id
straight into the key
argument. Maybe someone later will pop up with the reason. For now, to obtain the result I expected, I split the key into key and subkey
and passed assetData
separated from _id
. The final code is:
const array = [
{ _id:" 5fbcca92c36b24d99395623d",
assetData:
{ _id: "5fbcca159ae5f2d8ed792542",
name: 'House 1',
numberOfRooms: '1',
numberOfBathrooms: '2' } },
{ _id: "5fbcca92c36b24d99395623c",
assetData:
{ _id: "5fbcca159ae5f2d8ed792542",
name: 'House 1',
numberOfRooms: '1',
numberOfBathrooms: '2' } },
{ _id: "5fbccb32c36b24d993956242",
assetData:
{ _id: "5fbbedcb4decb58513e4ba80",
name: 'House 2',
numberOfRooms: '1',
numberOfBathrooms: '1' } },
{ _id: "5fbccb32c36b24d993956243",
assetData:
{ _id: "5fbbedcb4decb58513e4ba80",
name: 'House 2',
numberOfRooms: '1',
numberOfBathrooms: '1' } },
];
const groupBy = function (xs, key, subkey) {
return xs.reduce(function (rv, x) {
(rv[x[key][subkey]] = rv[x[key][subkey]] || []).push(x);
return rv;
}, {});
};
const test = Object.entries(groupBy(array, "assetData", "_id"))
console.log(test)
I'm open to more enlightened answers!