TypeScript中实现对象数组的级联多属性排序

TypeScript中实现对象数组的级联多属性排序

本文详细介绍了在typescript中对对象数组进行级联多属性排序的通用方法。首先,我们探讨了如何通过指定属性键的优先级顺序进行基础排序;接着,进一步展示了如何集成自定义比较器以处理特定类型或复杂逻辑的排序需求,确保排序过程的类型安全和灵活性。

理解级联排序需求

在处理复杂数据结构时,我们经常需要根据多个条件对数据进行排序。级联排序(Cascading Sort)指的是当主要排序属性的值相同时,才依据次要排序属性进行比较,以此类推,直到找到差异或所有属性都比较完毕。例如,我们可能需要先按状态排序,如果状态相同,则按日期排序。这种需求在TypeScript中实现时,需要兼顾类型安全和代码的通用性。

基于属性键的通用级联排序

最直接的级联排序方式是指定一个属性键的优先级列表。TypeScript的类型系统允许我们通过 keyof T 来安全地引用对象的属性名,从而构建一个通用的排序函数。

核心思路

该方法的核心是利用 Array.prototype.sort() 方法,并在其比较函数中迭代提供的属性键列表。对于每一对被比较的对象 item1 和 item2,我们依次检查每个属性。如果某个属性的值不相等,则直接返回该属性的比较结果(-1 或 1);如果所有属性的值都相等,则认为这两个对象是相等的,返回 0。

示例代码

interface Item {  a: string;  b: number;  c: Date;}/** * 对对象数组进行级联多属性排序 * @param items 要排序的对象数组 * @param keys 排序属性的优先级列表 */function sortByKeys(items: T[], keys: (keyof T)[]): void {  items.sort((item1, item2) => {    for (const key of keys) {      const v1 = item1[key];      const v2 = item2[key];      // 默认比较逻辑:v1 小于 v2 返回 -1,v1 大于 v2 返回 1,相等则继续下一个键      if (v1 < v2) return -1;      if (v2 < v1) return 1;    }    // 所有指定键的值都相等    return 0;  });}// 示例数据const items: Item[] = [  { a: 'aa', b: 1, c: new Date('2023-01-03T10:00:00Z') },  { a: 'a', b: 2, c: new Date('2023-01-01T10:00:00Z') },  { a: 'a', b: 1, c: new Date('2023-01-02T10:00:00Z') },  { a: 'b', b: 1, c: new Date('2023-01-01T10:00:00Z') },];console.log('原始数据:', JSON.parse(JSON.stringify(items))); // 按照 'b' 属性升序,如果 'b' 相同则按 'a' 属性升序排序sortByKeys(items, ['b', 'a']);console.log('按b(升), a(升)排序后:', items);/* 预期输出(日期部分可能因格式化不同而略有差异,但顺序一致):[  { a: 'a', b: 1, c: Date('2023-01-02T10:00:00Z') },  { a: 'aa', b: 1, c: Date('2023-01-03T10:00:00Z') },  { a: 'b', b: 1, c: Date('2023-01-01T10:00:00Z') },  { a: 'a', b: 2, c: Date('2023-01-01T10:00:00Z') }]*/

注意事项

此方法适用于属性值可以直接使用 运算符进行比较的类型(如 string, number, Date)。排序是原地进行的,会修改原始数组。如果需要保留原始数组,请先创建数组的副本(例如 […items].sort(…))。

实现自定义比较逻辑的级联排序

在某些情况下,简单的 比较可能不足以满足需求。例如,日期可能需要特定的降序比较逻辑,或者某些自定义对象需要基于其内部结构的比较。为了应对这些场景,我们可以扩展 sortByKeys 函数,使其能够接受针对特定属性的自定义比较器。

定义自定义比较器类型

首先,我们需要定义一个通用的自定义比较器类型。它接受两个相同类型的值,并返回一个表示它们相对顺序的数字(-1 表示第一个值小于第二个,0 表示相等,1 表示第一个值大于第二个)。

type CustomSorter = (value1: T, value2: T) => -1 | 0 | 1;

增强型 sortByKeys 函数

新的 sortByKeys 函数将额外接受一个 customSorters 对象,该对象将属性键映射到对应的 CustomSorter。

interface Item {  a: string;  b: number;  c: Date;}/** * 对对象数组进行级联多属性排序,支持自定义比较器 * @param items 要排序的对象数组 * @param keys 排序属性的优先级列表 * @param customSorters 可选的自定义比较器对象,键为属性名,值为该属性的比较函数 */function sortByKeys(  items: T[],   keys: (keyof T)[],   customSorters: Partial<{ [key in (keyof T)]: CustomSorter}> = {}): void {  items.sort((item1, item2) => {    for (const key of keys) {      const v1 = item1[key];      const v2 = item2[key];      const customSorter = customSorters[key]; // 获取当前属性的自定义比较器      if (customSorter) {        // 如果存在自定义比较器,则使用它        const result = customSorter(v1, v2);        if (result !== 0) return result; // 如果不相等,返回比较结果      } else {        // 否则使用默认比较逻辑        if (v1 < v2) return -1;        if (v2  new Date(Date.now() + Math.floor(Math.random() * 10000000));// 示例数据const itemsWithDates: Item[] = [  { a: 'aa', b: 1, c: randomDate() },  { a: 'a', b: 2, c: randomDate() },  { a: 'a', b: 1, c: randomDate() },  { a: 'b', b: 1, c: randomDate() },];console.log('n原始带日期数据:', JSON.parse(JSON.stringify(itemsWithDates)));// 按照 'c' 属性(日期)降序排序,并提供自定义日期比较器sortByKeys(itemsWithDates, ['c'], {  'c': (date1, date2) => {    // 日期降序排序:date1 晚于 date2 则 date1 排在前面(-1)    if (date1 > date2) return -1;     if (date2 > date1) return 1;      return 0;  },});console.log('按c(日期降序)排序后:', itemsWithDates);// 示例:多属性级联排序,其中一个属性使用自定义比较器const complexItems: Item[] = [  { a: 'apple', b: 5, c: new Date('2023-01-05T10:00:00Z') },  { a: 'banana', b: 2, c: new Date('2023-01-01T10:00:00Z') },  { a: 'apple', b: 2, c: new Date('2023-01-03T10:00:00Z') },  { a: 'banana', b: 5, c: new Date('2023-01-02T10:00:00Z') },  { a: 'apple', b: 5, c: new Date('2023-01-01T10:00:00Z') },];console.log('n原始复杂数据:', JSON.parse(JSON.stringify(complexItems)));// 优先级:b (升序) -> a (升序) -> c (降序)sortByKeys(complexItems, ['b', 'a', 'c'], {  'c': (date1, date2) => {    if (date1 > date2) return -1;    if (date2 > date1) return 1;    return 0;  },});console.log('按b(升), a(升), c(降)排序后:', complexItems);

类型解释

customSorters: Partial}> = {}:keyof T:获取类型 T 的所有属性名组成的联合类型。[key in (keyof T)]:这是一个映射类型,它遍历 T 的所有属性键。CustomSorter:对于每个属性键 key,其值类型是 T[key],所以对应的比较器类型是 CustomSorter。这确保了为特定属性提供的比较器只能处理该属性类型的值,提供了强大的类型安全。{ … }:创建了一个

以上就是TypeScript中实现对象数组的级联多属性排序的详细内容,更多请关注创想鸟其它相关文章!

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

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月21日 02:10:32
下一篇 2025年12月21日 02:10:42

相关推荐

  • 如何将json转换成html格式

    将json转换成html格式的方法:1、使用【/ui2/cl_json=>serialize】来生成JSON串;2、调用 【TRANSFORMATION sjson2html】来转换HTML。 本教程操作环境:windows10系统、html5版,DELL G3电脑,该方法适用于所有品牌电脑。…

    2025年12月21日 好文分享
    000
  • 在html中嵌入js代码的方法

    如何在HTML页面中嵌入javascript代码 (学习视频分享:html视频教程) document.write(“Hello World!”); 上面的代码会在 HTML 页面中产生这样的输出: Hello World! 实例解释: 立即学习“前端免费学习笔记(深入)”; 如果需要把一段 Jav…

    2025年12月21日
    000
  • 利用html+css+js实现简单的点赞效果

    我们在浏览其他网站的文章时,经常可以看到文章尾部有点赞收藏效果,非常有趣。今天我们自己动手来实现该效果。 (学习视频推荐:html视频教程) css样式 .like{ font-size:66px; color:#ccc; cursor:pointer;}.cs{color:#f00;} html内…

    2025年12月21日
    000
  • 在html页面中加入js可以用什么方法

    方法一:在head标签内引入JS文件 (推荐教程:html教程) 方法二:在body标签内写JS代码 //在这里面写你的js代码 </html 以上就是在html页面中加入js可以用什么方法的详细内容,更多请关注创想鸟其它相关文章!

    2025年12月21日
    000
  • 手把手教你如何在HTML中引入外部JS文件

    在学习前端的时候,小伙伴们一定对于在HTML中如何引入外部JS文件感到困惑,下面小编教你HTML引入外部JS文件的方法。 在引入外部JS文件的情况下,不能在之间插入代码,插入的代码不执行,只执行引入的外部文件。 attack.html 代码: 系好安全带,准备启航 attack.js 代码 func…

    2025年12月21日
    000
  • 自学 HTML5 要多久

    自学 HTML5 要多久 前端除了HTML5之外还有JavaScript和Css,如果只学习HTML5的话半个月到一个月之间就能学会,但是仅仅HTML5是不够的,还需要学习JavaScript和CSS这些,基础学习一个月也足够了。 JavaScript JavaScript(简称“JS”) 是一种具…

    2025年12月21日
    000
  • 使用html+css+js实现弹球游戏

    使用html+css+js实现弹球游戏  代码如下,复制即可使用: .panel{ position: relative; z-index: 0; top:0px; left: 400px; width: 300px; height: 500px; } .console{ position: abs…

    2025年12月21日
    000
  • html实现自动清理js、css文件的缓存

    方法如下: 1、手动清除浏览器缓存; 2、添加版本号(如 layout.css?v=1) 个人认为方法2更快,因为清除浏览器缓存还要等浏览器响应。但是每次更改版本号也很麻烦,所以需要想办法自动添加版本号。 (推荐教程:html教程) 立即学习“前端免费学习笔记(深入)”; 方法一:可以通过js自动给…

    2025年12月21日
    000
  • web开发之文件上传的多种实现方式(附代码)

    文件上传是 web 开发常见需求,上传文件需要用到文件输入框,如果给文件输入框添加一个 multiple 属性则可以一次选择多个文件(不支持的浏览器会自动忽略这个属性) 点击这个输入框就可以打开浏览文件对话框选择文件了,一般一个输入框上传一个文件就行,要上传多个文件也可以用多个输入框来处理,这样做是…

    2025年12月21日
    000
  • HTML怎么引入js文件?

    在html中可以使用标签,通过 src 属性来引入js文件。 标签用于定义客户端脚本,比如 javascript。 script标签元素既可以包含脚本语句,也可以通过 src 属性指向外部脚本文件。必需的 type 属性规定脚本的 MIME 类型。 示例: 建立一个外部的js文件(hello.js)…

    2025年12月21日
    000
  • 使用Hbuilder打包WebApp

    hbuilder是dcloud(数字天堂)推出的一款支持html5的web开发ide。该软件既可以支持web代码编写,也可以将已经编写好的项目代码打包为手机app。 HBuilder提供的打包有云端打包和本地打包两种,云端打包的特点是DCloud官方配置好了原生的打包环境,可以把HTML等文件编译为…

    2025年12月21日 好文分享
    000
  • html css js是什么?

    html称为超文本标记语言,是一种标识性的语言;css表示层叠样式表,是一种用来表现HTML或XML等文件样式的计算机语言;js全称为JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的高级编程语言。 在现今的互联网生活中,我们经常能看见CSS,HTML,js放在一起,却有很多人都…

    2025年12月21日
    000
  • js为什么那么难

    这个问题我就不等大家的回答了,相信大家也明白,我并不是闲的无聊这么问。js本身语法并不难,它困难的地方在哪呢?主要在于以下几点: 1,怎么样去把具象的问题抽象化 就是面对一个很具体的需求时,例如时,,一个网上商城吧,它内部的各种交互纷繁复杂。那么你是如何入手去写呢?前端架构也是需要设计的,这就看你是…

    2025年12月21日
    000
  • html5中怎么用js?

    在html5中可以直接在页面中嵌入JavaScript代码和包含外部JavaScript文件,嵌入脚本的语法是“”,外部脚本的语法是“”。 在html5中可以通过标签以两种方式(嵌入脚本和外部脚本)来使用js代码。下面本篇文章给大家介绍一下,希望对大家有所帮助。 在html5中使用js的两种方法: …

    2025年12月21日
    000
  • Web应用中富交互的撤销与前进操作的实现方法介绍(代码)

    本篇文章给大家带来的内容是关于web应用中富交互的撤销与前进操作的实现方法介绍(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 在web应用中,用户在进行一些富交互行为的操作时难免会出现误操作,比如在富文本编辑器设置错了字体颜色就需要撤回,做H5活动页面的时候不小心删了一个图…

    2025年12月21日
    000
  • JS实现简易版贪吃蛇小游戏

    新建网页 //① 绘制地图 function Map() { //私有成员(不会随便发生变化) var w = 800; var h = 400; //成员方法,绘制地图 this.showmap = function () { //创建p、设置css样式、追加给body var tu = docu…

    好文分享 2025年12月21日
    000
  • 如何利用js拼接html字符串

    下面小编就为大家带来一篇js拼接html字符串的注意事项。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 +加好拼接如果不换行,是不会出现执行一段一段执行的情况,但是字符串太长了,换行之后会出现一段一段执行的情况,这样页面生成的p等就不是想要的结果了。 换行要这样拼接 …

    好文分享 2025年12月21日
    000
  • 如何用JS实现直接运行html的代码

    这篇文章主要介绍了js实现直接运行html代码的方法,涉及javascript窗口操作相关实现技巧,需要的朋友可以参考下 本文实例讲述了JS实现直接运行html代码的方法。分享给大家供大家参考,具体如下: 1、实例代码: 直接运行 html 代码 document.getElementById(‘b…

    2025年12月21日
    000
  • js+html5实现页面可刷新的倒计时效果

    这篇文章主要为大家详细介绍了js+html5实现页面可刷新的倒计时效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 写了一个5分钟倒计时的代码,有的时候代码需要刷新,然后倒计时又从4:59开始了,我想到的一个解决办法,就是使用缓存,将开始倒计时的时间加上要倒计时的5分钟设为缓存,然后直接用这个…

    好文分享 2025年12月21日
    000
  • js获取Html元素的实际宽度高度的方法

    下面小编就为大家带来一篇js获取html元素的实际宽度高度的方法。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 第一种情况就是宽高都写在样式表里,就比如#p1{width:120px;}。这中情况通过#p1.style.width拿不到宽度,而通过#p1.offsetW…

    好文分享 2025年12月21日
    000

发表回复

登录后才能评论
关注微信