Array grouping in JavaScript: array.groupBy()
Original: https://dmitripavlutin.com/javascript-array-group/
Many developers prefer the Ruby programming language due to its rich library of standard utilities. For example, array in Ruby there are a number of methods.
JavaScript has also gradually enriched its standard library for strings and arrays. For example, in a previous post I described the new array.at() method.
Today's protagonist is the new array group proposal (currently in phase 3) which introduces new methods array.groupBy()
and array.groupByToMap()
. Their polyfills are available in the core-js
Let's see how you can benefit from the grouping approach.
1.array.groupBy ()
You have a list of products where each product is an object with 2 properties: name
and category
.
const products = [
{ name: 'apples', category: 'fruits' },
{ name: 'oranges', category: 'fruits' },
{ name: 'potatoes', category: 'vegetables' }
];
In the example above products
is an array of product objects.
Now you have to perform a simple operation on the product list - group products by category.
const groupByCategory = {
'fruits': [
{ name: 'apples', category: 'fruits' },
{ name: 'oranges', category: 'fruits' },
],
'vegetables': [
{ name: 'potatoes', category: 'vegetables' }
]
};
How do you get an array of groupByCategory
products
?
The usual way is for array.reduce()
call the method with the correct callback function:
const groupByCategory = products.reduce((group, product) => {
const { category } = product;
group[category] = group[category] ?? [];
group[category].push(product);
return group;
}, {});
console.log(groupByCategory);
// {
// 'fruits': [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ],
// 'vegetables': [
// { name: 'potatoes', category: 'vegetables' }
// ]
// }
products.reduce((acc, product) => { ... })
reduces the products
array to product objects grouped by category.
While I do think the array.reduce()
method is useful and powerful, sometimes its readability isn't the best.
Because grouping data is a frequently occurring task ( GROUP BY
from SQL?), the array group proposal introduces two useful methods: array.groupBy()
and array.groupByToMap()
.
Here's array.groupBy()
creates the same grouping by category:
const groupByCategory = products.groupBy(product => {
return product.category;
});
console.log(groupByCategory);
// {
// 'fruits': [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ],
// 'vegetables': [
// { name: 'potatoes', category: 'vegetables' }
// ]
// }
products.groupBy(product => {...})
returns an object with the key for each property as the category name and the value as an array containing the products of the corresponding category.
Grouping using products.groupBy()
requires less code and is easier to understand than using product.reduce()
.
array.groupBy(callback)
accepts a callback function called with 3 arguments: the current array item, the index, and the array itself. callback
should return a string: the group name where you want to add the item.
const groupedObject = array.groupBy((item, index, array) => {
// ...
return groupNameAsString;
});
2.array.groupByToMap ()
Sometimes you may want to use Map
instead of plain objects, because Map
is that it accepts any data type as keys, but plain objects are limited to strings and symbols.
So if you want to group data into one Map
, you can use the method array.groupByToMap()
.
array.groupByToMap(callback)
works exactly like array.groupBy(callback)
, except it groups items into Map
instead of normal JavaScript objects.
For example, to group the products array into a map by category name, do the following:
const groupByCategory = products.groupByToMap(product => {
return product.category;
});
console.log(groupByCategory);
// Map([
// ['fruits', [
// { name: 'apples', category: 'fruits' },
// { name: 'oranges', category: 'fruits' },
// ]],
// ['vegetables', [
// { name: 'potatoes', category: 'vegetables' }
// ]
// ])
3. Conclusion
If you want to easily group items in an array (similar to GROUP BY
SQL) then the new methods array.groupBy()
and array.groupByToMap()
.
Both functions accept a callback that should return the key of the group that must be inserted into the current item.
array.groupBy()
combines items into a normal JavaScript object, while array.groupByToMap()
combines them into an instance of Map
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。