# 数组元素分组(Group By)
# 概述
groupBy 函数是一个灵活的数组分组工具,它可以根据指定的条件将数组元素分组到不同的集合中。与 categorizeBy 相比,groupBy 提供了更强大的功能,它不仅支持按属性名分组,还支持通过自定义函数来确定分组规则。这使得它在处理各种复杂的数据分组场景时非常有用。
# 版权信息
版权所有 © 2024 xxm
# 函数签名
/**
* 根据指定条件对数组元素进行分组。
*
* @template T - 数组元素的类型。
* @template K - 分组键的类型,默认为 string。
* @param {T[]} array - 要分组的数组。
* @param {(item: T) => K | keyof T} grouper - 分组函数或属性名。如果是函数,将用其返回值作为分组键;如果是字符串,将用该属性的值作为分组键。
* @returns {Record<string, T[]>} - 分组后的对象,其中每个键是分组值(转为字符串),对应的值是该分组的元素数组。
*/
export function groupBy<T extends object, K = string>(
array: T[],
grouper: ((item: T) => K) | keyof T
): Record<string, T[]>;
# 参数
array: 要分组的对象数组。grouper: 分组依据,可以是一个函数或属性名:- 如果是函数,该函数接收数组中的每个元素作为参数,并返回一个值作为分组键。
- 如果是字符串,将使用该属性名在数组元素中对应的值作为分组键。
# 返回值
- 返回一个以字符串为键、对象数组为值的对象。每一个键都是分组值(转换成字符串形式),而对应的值则是所有属于该分组的对象组成的数组。
# 示例用法
# 1. 使用属性名进行分组
import { groupBy } from 'xxm-test-js';
const fruits = [
{ name: 'Apple', type: 'fruit' },
{ name: 'Carrot', type: 'vegetable' },
{ name: 'Banana', type: 'fruit' },
{ name: 'Broccoli', type: 'vegetable' },
];
const groupedByType = groupBy(fruits, 'type');
console.log(groupedByType);
// 输出:
// {
// fruit: [{ name: 'Apple', type: 'fruit' }, { name: 'Banana', type: 'fruit' }],
// vegetable: [{ name: 'Carrot', type: 'vegetable' }, { name: 'Broccoli', type: 'vegetable' }]
// }
# 2. 使用自定义函数进行分组
import { groupBy } from 'xxm-test-js';
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 },
{ name: 'David', age: 35 },
{ name: 'Eve', age: 30 },
];
// 根据年龄范围分组
const groupedByAgeRange = groupBy(users, (user) => {
if (user.age < 25) return 'young';
if (user.age < 35) return 'middle';
return 'old';
});
console.log(groupedByAgeRange);
// 输出:
// {
// middle: [
// { name: 'Alice', age: 25 },
// { name: 'Bob', age: 30 },
// { name: 'Charlie', age: 25 },
// { name: 'Eve', age: 30 }
// ],
// old: [{ name: 'David', age: 35 }]
// }
# 3. 基于计算属性进行分组
import { groupBy } from 'xxm-test-js';
const products = [
{ name: 'Product A', price: 10, category: 'electronics' },
{ name: 'Product B', price: 20, category: 'clothing' },
{ name: 'Product C', price: 15, category: 'electronics' },
{ name: 'Product D', price: 25, category: 'clothing' },
];
// 根据价格和类别的组合进行分组
const groupedByCategoryAndPrice = groupBy(
products,
(product) => `${product.category}-${product.price > 15 ? 'expensive' : 'cheap'}`
);
console.log(groupedByCategoryAndPrice);
// 输出:
// {
// 'electronics-cheap': [{ name: 'Product A', price: 10, category: 'electronics' }],
// 'clothing-expensive': [{ name: 'Product B', price: 20, category: 'clothing' }],
// 'electronics-cheap': [{ name: 'Product C', price: 15, category: 'electronics' }],
// 'clothing-expensive': [{ name: 'Product D', price: 25, category: 'clothing' }]
// }
# 注意事项
- 当数组元素不是对象或为
null时,这些元素将被忽略。 - 如果使用属性名作为分组依据,但该属性在元素中不存在或值为
undefined,该元素将被忽略。 - 所有的分组键都会被转换为字符串,以确保它们可以作为对象的有效键。
# 与 categorizeBy 的区别
groupBy 函数是 categorizeBy 的增强版本,提供了更灵活的分组能力:
categorizeBy只能根据对象的属性名进行分组。groupBy不仅可以根据属性名分组,还可以使用自定义函数来生成更复杂的分组规则。