0%

javascript-object.prototype.groupBy

JavaScript Object.prototype.groupBy

给定如下对象数组,如何按照type进行分组?

1
2
3
4
5
6
7
const inventory = [
{ name: "asparagus", type: "vegetables", quantity: 5 },
{ name: "bananas", type: "fruit", quantity: 0 },
{ name: "goat", type: "meat", quantity: 23 },
{ name: "cherries", type: "fruit", quantity: 5 },
{ name: "fish", type: "meat", quantity: 22 },
];

最直观的做法如下,遍历数组,然后取出每个对象的type字段,按照哈希表归类的方式进行分组,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
function groupBy(arr, key) {
const result = [];
for (const item of inventory) {
const { type } = item;
if (result[type]) {
result[type].push(item);
} else {
result[type] = [item];
}
}

return result;
}

当然,也可以是用reduce函数,注意下面代码中acc的初始值是{},因为我们显示传递了{}给reduce函数。

1
2
3
4
5
6
7
8
9
10
const groupBy = (arr, key) => {
return arr.reduce((acc, item) => {
const group = item[key];
if (!acc[group]) {
acc[group] = [];
}
acc[group].push(item);
return acc;
}, {});
};

最后,你还可以使用groupBy, 只是这个方法比较新( Chrome 117 or later and Node.js 21.0.0 or later),要注意兼容性。

1
2
const result = Object.groupBy(inventory, ({ type }) => type);
console.log(result);

output:

1
2
3
4
5
6
7
8
9
10
11
12
{
vegetables: [ { name: 'asparagus', type: 'vegetables', quantity: 5 } ],
fruit: [
{ name: 'bananas', type: 'fruit', quantity: 0 },
{ name: 'cherries', type: 'fruit', quantity: 5 }
],
meat: [
{ name: 'goat', type: 'meat', quantity: 23 },
{ name: 'fish', type: 'meat', quantity: 22 }
]
}

References:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy