Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
JavaScript 数组高级分组:按相邻元素属性动态切片_创想鸟

JavaScript 数组高级分组:按相邻元素属性动态切片

JavaScript 数组高级分组:按相邻元素属性动态切片

本文详细讲解如何利用JavaScript的Array.prototype.reduce()方法,实现一种特殊的数组分组逻辑。该方法根据数组中相邻元素的特定属性值(如number)是否发生变化,动态地将原始数组切片成多个子数组。当属性值连续相同时,元素被归入当前子数组;一旦属性值改变,则开启一个新的子数组,从而高效地实现按序的结构化数据重组。

在数据处理和前端开发中,我们经常需要对数组进行分组操作。传统的分组通常基于某个固定属性值,将所有具有相同属性值的元素归为一组。然而,有时我们会遇到一种特殊需求:需要根据元素在数组中的顺序,以及相邻元素之间某个特定属性值的变化来动态地进行分组。例如,给定一个对象数组,我们希望将连续的、某个属性值相同的对象归为一个子数组,一旦该属性值发生变化,就开启一个新的子数组。

核心概念:按相邻元素属性动态分组

这种分组逻辑的核心在于“变化检测”。当我们遍历数组时,需要实时比较当前元素的某个属性值与前一个元素的该属性值。

如果当前元素的属性值与前一个元素相同,则它应该被添加到当前正在构建的子数组中。如果当前元素的属性值与前一个元素不同,则意味着一个新的分组开始了,我们需要创建一个新的子数组来包含当前元素。

对于数组的第一个元素,由于没有前一个元素可以比较,它自然会开启第一个分组。

使用 Array.prototype.reduce() 实现

Array.prototype.reduce() 方法是实现这种动态分组的理想工具。它允许我们遍历数组,并累积一个结果,这个结果可以是任何类型,包括一个包含多个子数组的数组。

让我们通过一个具体的示例来理解其实现。假设我们有以下数据结构:

立即学习“Java免费学习笔记(深入)”;

const data = [  {name: 'A', number: 1, order: 1},  {name: 'B', number: 1, order: 2},  {name: 'C', number: 1, order: 3},  {name: 'D', number: 2, order: 4},  {name: 'E', number: 2, order: 5},  {name: 'F', number: 1, order: 6}];

我们的目标是将其转换为:

[  [    {name: 'A', number: 1, order: 1},    {name: 'B', number: 1, order: 2},    {name: 'C', number: 1, order: 3},  ],  [    {name: 'D', number: 2, order: 4},    {name: 'E', number: 2, order: 5},  ],  [    {name: 'F', number: 1, order: 6}  ]]

可以看到,当number属性从1变为2(C到D),或从2变为1(E到F)时,都会开启新的子数组。

示例代码

const data = [  {"name":"A","number":1,"order":1},  {"name":"B","number":1,"order":2},  {"name":"C","number":1,"order":3},  {"name":"D","number":2,"order":4},  {"name":"E","number":2,"order":5},  {"name":"F","number":1,"order":6}];let result = data.reduce((accumulator, currentObject, currentIndex, array) => {  // 获取前一个对象的 'number' 属性值。  // 使用可选链操作符 '?' 处理第一个元素 (currentIndex === 0) 的情况,  // 此时 array[currentIndex - 1] 为 undefined,其 .number 属性也将是 undefined。  const previousNumber = array[currentIndex - 1]?.number;  // 检查当前对象的 'number' 属性是否与前一个对象的 'number' 属性不同。  // 对于第一个元素,previousNumber 是 undefined,而 currentObject.number 是实际值,  // 所以它们必然不同,从而正确地开始第一个分组。  if (previousNumber !== currentObject.number) {    // 如果不同,说明需要开始一个新的分组。    // 将包含当前对象的数组推入累加器中。    accumulator.push([currentObject]);  } else {    // 如果相同,说明当前对象属于上一个分组。    // 将当前对象推入累加器中最后一个子数组。    accumulator[accumulator.length - 1].push(currentObject);  }  // 返回累加器,供下一次迭代使用。  return accumulator;}, []); // 初始累加器为空数组,用于存放所有分组。console.log(result);

代码解析

data.reduce((accumulator, currentObject, currentIndex, array) => { … }, []):

accumulator (a): 这是一个数组,用于累积最终的分组结果(即一个包含多个子数组的数组)。currentObject (c): 当前正在处理的数组元素。currentIndex (i): 当前元素的索引。array (d): 原始数组(data本身),这使得我们可以访问前一个元素。[]: reduce 方法的第二个参数,表示 accumulator 的初始值,这里是一个空数组。

const previousNumber = array[currentIndex – 1]?.number;:

array[currentIndex – 1]:获取前一个元素。?.number:使用可选链操作符。这在 currentIndex 为 0 时非常有用,因为 array[-1] 会是 undefined,undefined?.number 会安全地返回 undefined 而不会抛出错误。

if (previousNumber !== currentObject.number):

这是核心的判断逻辑。它检查当前元素的 number 属性是否与前一个元素的 number 属性不同。对于第一个元素(currentIndex = 0),previousNumber 是 undefined。由于 undefined 不等于任何有效的 number 值(如 1 或 2),这个条件会为真,从而确保第一个元素总是开启一个新的分组。

accumulator.push([currentObject]);:

如果 number 属性不同,说明需要开始一个新的分组。我们将当前对象 currentObject 包装在一个新的数组 [currentObject] 中,并将其推入 accumulator。

accumulator[accumulator.length – 1].push(currentObject);:

如果 number 属性相同,说明当前对象属于上一个分组。我们通过 accumulator[accumulator.length – 1] 访问 accumulator 中最后一个(即当前正在构建的)子数组,并将 currentObject 推入其中。

return accumulator;:

每次迭代结束时,必须返回 accumulator 的当前状态,以便在下一次迭代中使用。

简洁写法(逗号表达式)

原始答案中使用了逗号表达式来简化代码,避免了 if/else 和 return 关键字。

const data = [{"name":"A","number":1,"order":1},{"name":"B","number":1,"order":2},{"name":"C","number":1,"order":3},{"name":"D","number":2,"order":4},{"name":"E","number":2,"order":5},{"name":"F","number":1,"order":6}];let result = data.reduce((a,c,i,d)=>  (d[i-1]?.number!==c.number ? a.push([c]) : a[a.length-1].push(c), a), [])console.log(result)

逗号表达式 (expr1, expr2, …, exprN) 会从左到右依次执行每个表达式,并返回最后一个表达式的值。在这个例子中:

d[i-1]?.number!==c.number ? a.push([c]) : a[a.length-1].push(c) 是一个三元运算符,它的结果(push 方法的返回值,即新数组的长度)会被忽略。a 是逗号表达式的最后一个部分,因此 reduce 回调函数会返回 a(即 accumulator)。这种写法非常紧凑,但在可读性上可能不如带有 if/else 的版本直观,尤其对于初学者而言。

注意事项

数据顺序的重要性: 这种分组方法是严格依赖于原始数组中元素的顺序的。如果原始数组的顺序发生变化,或者数据不是按顺序排列的,那么分组结果也会随之改变,可能无法达到预期效果。第一个元素的处理: array[currentIndex – 1]?.number 的设计巧妙地处理了第一个元素的情况。当 currentIndex 为 0 时,array[currentIndex – 1] 是 undefined,undefined?.number 也是 undefined。由于 undefined 不等于任何有效的 number 值,第一个元素总会被推入一个新的子数组中,从而正确地开始第一个分组。属性值的类型: 本教程以 number 属性为例,但这种方法同样适用于其他可比较的属性类型,如字符串 (string) 或布尔值 (boolean)。只要能够通过 !== 进行有效比较即可。性能考量: reduce 方法在处理大型数组时通常是高效的。这种线性遍历一次数组的方案,时间复杂度为 O(n),其中 n 是数组的长度。

总结

通过巧妙地利用 Array.prototype.reduce() 方法,结合对相邻元素属性的比较,我们可以实现一种强大且灵活的数组分组逻辑。这种方法特别适用于需要根据数据流中某个特定属性的变化来动态切分数组的场景,例如日志分析、时间序列数据处理或任何需要按序分组的业务需求。理解并掌握这种模式,将极大地增强您在 JavaScript 中处理复杂数据结构的能力。

以上就是JavaScript 数组高级分组:按相邻元素属性动态切片的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1513660.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
JavaScript数组:基于属性值连续变化的有序分组实现
上一篇 2025年12月20日 07:53:35
JavaScript 数组分组技巧:按顺序连续属性值分组对象
下一篇 2025年12月20日 07:53:50

相关推荐

  • composer home命令怎么查看主目录位置

    composer home命令怎么查看主目录位置composer home命令怎么查看主目录位置composer home命令怎么查看主目录位置composer home命令怎么查看主目录位置

    Composer的主目录可通过命令composer config –global home查看,该路径用于存储全局包缓存、配置文件等,默认在Linux/macOS为~/.composer,Windows为C:Users用户名AppDataRoamingComposer。 在使用 Comp…

    2026年10月5日 • 用户投稿
    300
  • 如何在Java中解析URL地址 Java URL类的使用方法详解

    如何在Java中解析URL地址 Java URL类的使用方法详解如何在Java中解析URL地址 Java URL类的使用方法详解如何在Java中解析URL地址 Java URL类的使用方法详解如何在Java中解析URL地址 Java URL类的使用方法详解

    java中解析url的核心是使用java.net.url类,它提供getprotocol()、gethost()、getport()、getpath()、getquery()、getref()等方法提取url各部分;解析时需注意端口默认值、异常处理及url编码问题;可通过手动解析或借助apache …

    2026年10月5日 • 用户投稿
    300
  • win10怎么关闭自动播放功能_win10禁用U盘及其他设备自动播放的设置方法

    win10怎么关闭自动播放功能_win10禁用U盘及其他设备自动播放的设置方法win10怎么关闭自动播放功能_win10禁用U盘及其他设备自动播放的设置方法win10怎么关闭自动播放功能_win10禁用U盘及其他设备自动播放的设置方法win10怎么关闭自动播放功能_win10禁用U盘及其他设备自动播放的设置方法

    禁用Windows 10自动播放可防止U盘或光驱运行恶意程序。首先通过“设置→设备→自动播放”关闭全局功能;其次在控制面板中为各类媒体选择“不执行任何操作”;专业版用户可通过组策略编辑器启用“关闭自动播放”策略并设为“所有驱动器”;家庭版可修改注册表HKEY_LOCAL_MACHINE路径下新建No…

    2026年10月5日 • 用户投稿
    100
  • 夸克浏览器需要什么系统架构_CPU架构支持详情

    夸克浏览器需要什么系统架构_CPU架构支持详情夸克浏览器需要什么系统架构_CPU架构支持详情夸克浏览器需要什么系统架构_CPU架构支持详情夸克浏览器需要什么系统架构_CPU架构支持详情

    夸克浏览器支持ARM64架构,需iOS 12或Android 8.0以上系统,确保官方渠道下载ARM64版本安装包以避免兼容问题。 如果您尝试在设备上安装或运行夸克浏览器,但遇到兼容性问题,则可能是由于设备的CPU架构不受支持。以下是解决此问题的步骤: 本文运行环境:iPhone 15 Pro,iO…

    2026年10月5日 • 用户投稿
    100
  • win11怎么设置才能不自动更新驱动_Win11禁止驱动程序自动更新方法

    win11怎么设置才能不自动更新驱动_Win11禁止驱动程序自动更新方法win11怎么设置才能不自动更新驱动_Win11禁止驱动程序自动更新方法win11怎么设置才能不自动更新驱动_Win11禁止驱动程序自动更新方法win11怎么设置才能不自动更新驱动_Win11禁止驱动程序自动更新方法

    可通过组策略、系统设置、官方工具或禁用服务阻止Windows 11自动更新驱动。一、使用本地组策略编辑器,启用“阻止使用与下列设备安装程序类相匹配的驱动程序安装设备”,添加设备类GUID(如4d36e968-e325-11ce-bfc1-08002be10318)以阻止所有驱动更新;二、在“设置→W…

    2026年10月5日 • 用户投稿
    100
  • composer “path” 仓库类型如何处理版本约束

    composer “path” 仓库类型如何处理版本约束composer “path” 仓库类型如何处理版本约束composer “path” 仓库类型如何处理版本约束composer “path” 仓库类型如何处理版本约束

    Path仓库通过本地目录引入包,优先使用目标composer.json中的version字段匹配require约束;若版本不满足则报错,建议显式声明版本并启用symlink以提升开发效率。 当你在 Composer 中使用 “path” 类型的仓库时,版本约束的处理方式与从 …

    2026年10月5日 • 用户投稿
    000
  • Win7下用DVD Maker刻录光盘

    Win7下用DVD Maker刻录光盘Win7下用DVD Maker刻录光盘Win7下用DVD Maker刻录光盘Win7下用DVD Maker刻录光盘

    如何制作dvd光盘?虽然很多人习惯使用nero等第三方工具,但其实windows 7系统内置的windows dvd maker已足够满足日常需求。无需安装额外软件,只需插入空白dvd光盘,启动程序后导入视频或照片,选择菜单模板,调整播放顺序,最后点击刻录即可完成整个流程。操作界面友好直观,特别适合…

    2026年10月5日 • 用户投稿
    000
  • 茶卡盐湖回应游客将铺路盐装走:泡脚可以,不能食用

    茶卡盐湖回应游客将铺路盐装走:泡脚可以,不能食用茶卡盐湖回应游客将铺路盐装走:泡脚可以,不能食用茶卡盐湖回应游客将铺路盐装走:泡脚可以,不能食用茶卡盐湖回应游客将铺路盐装走:泡脚可以,不能食用

    近日,一处著名盐湖景点发生游客私自将路面盐块装袋带走的事件,引发社会关注。景区方面表示对此类行为并未明令禁止,但同时强调这些盐块为未经加工的天然盐。相关领域专家也发出健康预警,指出直接食用此类天然盐存在严重安全隐患。 景区回应游客取盐行为 1、根据现场目击者拍摄的画面,部分游客在游览过程中,使用塑料…

    2026年10月5日 • 用户投稿
    100
  • 如何为谷歌浏览器安装油猴插件_Tampermonkey脚本管理器的安装指南

    如何为谷歌浏览器安装油猴插件_Tampermonkey脚本管理器的安装指南如何为谷歌浏览器安装油猴插件_Tampermonkey脚本管理器的安装指南如何为谷歌浏览器安装油猴插件_Tampermonkey脚本管理器的安装指南如何为谷歌浏览器安装油猴插件_Tampermonkey脚本管理器的安装指南

    首先需安装Tampermonkey脚本管理器,可通过Chrome应用店搜索并添加扩展,或手动下载CRX文件在开发者模式下离线安装,最后可导入已有.js脚本恢复功能。 如果您尝试在谷歌浏览器中运行自定义脚本以增强网页功能,但缺少脚本管理工具,则可能是由于未安装脚本管理器。以下是解决此问题的步骤: 本文…

    2026年10月5日 • 用户投稿
    100
  • MySQL如何修改列数据类型 ALTER COLUMN注意事项汇总

    MySQL如何修改列数据类型 ALTER COLUMN注意事项汇总MySQL如何修改列数据类型 ALTER COLUMN注意事项汇总MySQL如何修改列数据类型 ALTER COLUMN注意事项汇总MySQL如何修改列数据类型 ALTER COLUMN注意事项汇总

    修改mysql列数据类型需谨慎,因可能引发数据丢失、性能下降及外键问题。1. 修改前务必备份数据,评估现有数据兼容性,检查是否存在不兼容值及精度损失;2. 若列涉及外键约束,需先删除外键,修改列类型后再重新添加,确保主外键类型一致;3. 修改后注意重建索引、分析查询计划、优化sql语句,必要时使用覆…

    2026年10月5日 • 用户投稿
    100
  • yandex入口_yandere首页入口_Yandex搜索引擎入口

    yandex入口_yandere首页入口_Yandex搜索引擎入口yandex入口_yandere首页入口_Yandex搜索引擎入口yandex入口_yandere首页入口_Yandex搜索引擎入口yandex入口_yandere首页入口_Yandex搜索引擎入口

    本文将为您详细介绍被称为“东欧谷歌”的Yandex,并提供其官方首页入口地址。通过本文,您将了解如何轻松访问Yandex,并发现它在图片搜索和多语言处理方面的独特优势。 1、立即进入“☞☞☞☞点击yandex搜索引擎入口☜☜☜☜”; 2、立即进入“☞☞☞☞点击yandex俄罗斯搜索引擎免费登录入口☜…

    2026年10月5日 • 用户投稿
    100
  • 架构必知:深入理解Linux I/O系统

    架构必知:深入理解Linux I/O系统架构必知:深入理解Linux I/O系统架构必知:深入理解Linux I/O系统架构必知:深入理解Linux I/O系统

    目录 传统的 System Call I/O读操作写操作网络 I/O磁盘 I/O高性能优化的 I/O存储设备的 I/O 栈I/O Buffering 传统的 System Call I/O 在 linux 系统中,传统的文件访问方式通过 write() 和 read() 两个系统调用来实现。通过 r…

    2026年10月5日 • 用户投稿
    100
  • Java中字符串分组求和:优化代码并保留数字前导零的显示

    Java中字符串分组求和:优化代码并保留数字前导零的显示Java中字符串分组求和:优化代码并保留数字前导零的显示Java中字符串分组求和:优化代码并保留数字前导零的显示Java中字符串分组求和:优化代码并保留数字前导零的显示

    本教程详细介绍了如何在Java中高效地处理随机生成的数字字符串,并根据指定长度对其进行分组求和。文章首先分析了使用ArrayList和数组的传统方法及其优化空间,随后展示了如何通过直接解析字符串来简化代码,减少不必要的中间数据结构。重点解决了在直接解析过程中,如何确保输出显示能够保留数字的前导零,同…

    2026年10月5日 • 用户投稿
    100
  • 如何在Linux系统中使用日志管理工具

    在linux操作系统中,日志管理是非常重要的一项工作,尤其对于系统管理员来说,它可以帮助他们有效地诊断和解决各种问题。本文将介绍一些常用的日志管理工具,以及如何在linux系统中使用它们。 Syslog-ngSyslog-ng是一个强大的、高度可定制的日志引擎,它可以帮助用户将来自各种设备和应用程序…

    2026年10月5日
    000
  • composer如何在一个旧项目中引入和管理依赖

    composer如何在一个旧项目中引入和管理依赖composer如何在一个旧项目中引入和管理依赖composer如何在一个旧项目中引入和管理依赖composer如何在一个旧项目中引入和管理依赖

    首先初始化Composer并创建composer.json文件,然后根据需求通过composer require引入必要依赖,接着在composer.json中配置autoload以支持现有代码结构,逐步替换旧代码并使用自动加载功能,在版本控制中提交composer.lock但忽略vendor目录,…

    2026年10月5日 • 用户投稿
    000
  • win8系统下如何格式化硬盘_Win8磁盘管理与格式化操作指南

    win8系统下如何格式化硬盘_Win8磁盘管理与格式化操作指南win8系统下如何格式化硬盘_Win8磁盘管理与格式化操作指南win8系统下如何格式化硬盘_Win8磁盘管理与格式化操作指南win8系统下如何格式化硬盘_Win8磁盘管理与格式化操作指南

    首先使用磁盘管理工具格式化硬盘,通过Win+X选择磁盘管理,右键分区执行格式化并设置NTFS文件系统;其次可通过文件资源管理器直接右键驱动器进行快速格式化;最后可使用管理员权限的命令提示符运行DiskPart,输入相应命令完成底层格式化操作。 如果您需要在Windows 8系统中对硬盘或分区进行清理…

    2026年10月5日 • 用户投稿
    000
  • AutoCAD 2008设置渲染平滑度0.3

    AutoCAD 2008设置渲染平滑度0.3AutoCAD 2008设置渲染平滑度0.3AutoCAD 2008设置渲染平滑度0.3AutoCAD 2008设置渲染平滑度0.3

    在autocad 2008中,若要将渲染对象的平滑度设置为0.3,可打开渲染设置对话框,选择“自定义”模式,并在质量参数中输入精确数值,从而实现理想的平滑效果。 1、 打开工具菜单,从中选取对应命令选项。 2、 在设置界面中找到渲染对象平滑度选项,将其值调整为0.3。 设计师AI工具箱 最懂设计师的…

    2026年10月5日 • 用户投稿
    000
  • Circuit Tracer— Anthropic开源的AI模型内部决策追踪工具

    Circuit Tracer— Anthropic开源的AI模型内部决策追踪工具Circuit Tracer— Anthropic开源的AI模型内部决策追踪工具Circuit Tracer— Anthropic开源的AI模型内部决策追踪工具Circuit Tracer— Anthropic开源的AI模型内部决策追踪工具

    circuit tracer 是 anthropic 推出的开源工具,旨在研究大型语言模型的工作原理。此工具利用生成归因图的方式展现模型生成特定输出时所经历的具体步骤。归因图能够帮助研究者追踪模型的决策流程,可视化特征间的关联,并检验各种假设。circuit tracer 支持多个流行的开源模型,比…

    2026年10月5日 • 用户投稿
    000
  • Composer如何自动加载不符合PSR规范的旧版PHP代码?

    Composer如何自动加载不符合PSR规范的旧版PHP代码?Composer如何自动加载不符合PSR规范的旧版PHP代码?Composer如何自动加载不符合PSR规范的旧版PHP代码?Composer如何自动加载不符合PSR规范的旧版PHP代码?

    通过配置classmap和files实现Composer对非PSR代码的自动加载:1. 使用classmap扫描legacy目录下的类、接口、trait并生成路径映射;2. 通过files引入全局函数或配置文件如helpers.php、config.php;3. 可与PSR-4共存,支持新旧代码混合…

    2026年10月5日 • 用户投稿
    000
  • 教你win7文件夹排序方法

    教你win7文件夹排序方法教你win7文件夹排序方法教你win7文件夹排序方法教你win7文件夹排序方法

    win7系统中如何对文件夹进行排序?不少用户反映,文件夹排列杂乱无章,一个个查找费时又费力。别担心,下面为大家带来一个简单实用的文件夹排序技巧,一起来看看具体操作步骤吧! 1、首先启动电脑,点击“计算机”图标进入主界面; 2、选择你需要操作的磁盘分区,双击打开进入该盘符; 3、此时可以看到里面存在大…

    2026年10月5日 • 用户投稿
    000

发表回复

登录后才能评论
关注微信