javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript groupBy

JavaScript中常用数据处理函数groupBy的用法详解

作者:进二开物

数据处理与分析中,对数据进行分组是非常常见的功能,不论是实际工作中,还是在面试的场景中应用十分广泛,尤其在函数式编程中 groupBy 十分常见,下面我们就来学习一下groupBy的用法吧

一、前言

数据处理与分析中,对数据进行分组是非常常见的功能,不论是实际工作中,还是在面试的场景中应用十分广泛。尤其在函数式编程中 groupBy 十分常见。在 JavaScript 中 groupBy 也已经进入了 JS 的标准。

二、介绍

groupBy 函数是一个用于对 数组元素 进行 分组 的实用函数。groupBy 允许我们指定分组条件,将数组的元素分为不同的组,用于数据处理或者展示。

三、标准

proposal-array-grouping: tc39.es/proposal-array-grouping/#sec-scope

Object.groupBy

Object.groupBy(items, callbackFn) // 语法,第一个参数是可迭代对象,第二参数是回调函数

Map.groupBy

Map.groupBy(items, callbackFn) // 语法,第一个参数是可迭代对象,第二参数是回调函数

四、环境支持

五、Object.groupBy 示例

const data = [
  { id: 1, type: 'A' },
  { id: 2, type: 'B' },
  { id: 3, type: 'A' },
  { id: 4, type: 'C' },
  { id: 5, type: 'B' },
];
const groupType = Object.groupBy(data, 'type') // ❌ 第二个参数必须是函数
const groupType = Object.groupBy(data, (item) => item.type) // ✅ 按照类型进行分类, 并且 type 就是 group 的 key 值。
// {
//   A: [{…}, {…}]
//   B: [{…}, {…}]
//   C: [{…}]
/ }

六、实现一个按照给 key 据分组

虽然函数通用性更加广泛,但是复杂度比直接传递数据要稍微高一点,这里实现一个按照传递属性方式实现一个 groupBy:

function groupBy(arr, key) {
  return arr.reduce((acc, obj) => {
    const groupKey = obj[key];
    acc[groupKey] = acc[groupKey] || [];
    acc[groupKey].push(obj);
    return acc;
  }, {});
}

// data 复用以上的 data
groupBy(data, 'type') // 输出结果与 Object.groupBy 一致

实现的核心思想就是 reduce 进行 累加。从 {} 对象开始,然后再对象上赋值对应key为空数组,符合这个key 的就进入此分组。

七、实现一个通用的 groupBy

有了基于 key 实现 groupBy 之后,实现通用的 groupBy 就比较容易了:

type KeyFunc<T> = (obj: T) => string

export function groupByWithFn<T>(
  array: T[],
  keyFunc: KeyFunc<T>
): Record<string, T[]> {
  return array.reduce((acc: Record<string, T[]>, obj: T) => {
    const key: string = keyFunc(obj)
    if (!acc[key]) {
      acc[key] = []
    }
    acc[key].push(obj)
    return acc
  }, {})
}

这里用 TS 实现主要约束类型,本质也非常简单就是 keyFunc 用当前的 obj 执行获取 key,如果没有获取到了,设置一个空的数组初始化,并将数据填充进去。重复累积这个过程。

八、lodash z中的 groupBy

_.groupBy(data, (item) => item.type)

lodash 将 groupBy 放在 collection 集合中,而非数组中。实用方式与以上基本一致。

九、rxjs groupBy

如果是函数式编程,当然离不开 RxJS 中数据操作。rxjs groupBy 不能单独的实现 js 中 groupBy 的功能,当然我们组合操作符或者自定义操作符实现。以下是实现一个自定义操作符 customGroupBy

import { Observable, of } from 'rxjs';
import { map, mergeMap, reduce } from 'rxjs/operators';

// 自定义 groupBy 操作符
function customGroupBy(keySelector) {
  return function (source) {
    return new Observable((observer) => {
      source.pipe(
        mergeMap((arr) => arr),
        reduce((acc, val) => {
          const key = keySelector(val);
          acc[key] = acc[key] || [];
          acc[key].push(val);
          return acc;
        }, {})
      ).subscribe({
        next: (result) => {
          observer.next(result);
          observer.complete();
        },
        error: (err) => observer.error(err),
      });
    });
  };
}

of([
    { id: 1, type: 'A' },
    { id: 2, type: 'B' },
    { id: 3, type: 'A' },
    { id: 4, type: 'C' },
    { id: 5, type: 'B' },
  ]).pipe(
  customGroupBy((obj) => obj.type)
).subscribe({
  next: (v) => {console.log(v)}
});

customGroupBy 操作符,接受一个函数作为参数,当然这个函数式是一个闭包,包含了 of 操作符中的静态数据。customGroupBy 是典型的自定义操作符实现,source 的就是 of 制作的静态可观察对象。后面的逻辑也是实用 reduce 进行累加计算。然后对外输出数据

十、groupBy 其他

十一、小结

本文主要介绍 JavaScript 中的 groupBy 函数实用特性。从 ES 标准草案,到自己实现一个简单的 groupBy, 再到 lodash 以及 RxJS 中实现 groupBy 效果。在函数式编程中,groupBy 实用特性非常高,在数据处理领域广泛适用。

到此这篇关于JavaScript中常用数据处理函数groupBy的用法详解的文章就介绍到这了,更多相关JavaScript groupBy内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文