JavaScripts数组里的对象排序的24个方法

2024-06-23 20:36

本文主要是介绍JavaScripts数组里的对象排序的24个方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 使用 Array.prototype.sort()

这是最基本、也是最常用的方法。sort() 方法会原地修改数组,并返回排序后的数组。你需要传入一个比较函数来定义排序逻辑。

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];// 按照年龄升序排序
array.sort((a, b) => a.age - b.age);
console.log(array);// 按照名字字母顺序排序
array.sort((a, b) => a.name.localeCompare(b.name));
console.log(array);

2. 使用 Array.prototype.map() 和 Array.prototype.sort()

这种方法适用于当你不想改变原始数组时,可以先创建一个新的数组,然后进行排序。

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];const sortedArray = array.map(item => item) // 复制数组.sort((a, b) => a.age - b.age);console.log(sortedArray);
console.log(array); // 原数组未改变

3. 使用 Array.prototype.slice() 和 Array.prototype.sort()

同样是为了不改变原数组,这种方法利用 slice() 创建一个数组的浅拷贝,然后进行排序。

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];const sortedArray = array.slice().sort((a, b) => a.age - b.age);
console.log(sortedArray);
console.log(array); // 原数组未改变

4. 使用 Array.prototype.reduce() 实现自定义排序

如果你需要对数组进行复杂的排序操作,可以使用 reduce() 方法。

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];const sortedArray = array.reduce((accumulator, currentValue) => {let i = 0;while (i < accumulator.length && accumulator[i].age < currentValue.age) {i++;}accumulator.splice(i, 0, currentValue);return accumulator;
}, []);console.log(sortedArray);

5. 使用第三方库(如 Lodash)

Lodash 提供了更强大的排序功能,如多属性排序。你需要先安装 Lodash:

npm install lodash

然后使用 Lodash 的 _.orderBy 方法:

const _ = require('lodash');const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];// 按照多个属性排序
const sortedArray = _.orderBy(array, ['age', 'name'], ['asc', 'asc']);
console.log(sortedArray);

6. 使用自定义比较函数进行多字段排序

如果你希望根据多个字段进行排序,可以编写自定义的比较函数。

const array = [{ name: 'Alice', age: 25, height: 165 },{ name: 'Bob', age: 22, height: 175 },{ name: 'Charlie', age: 22, height: 170 }
];// 按年龄升序,如果年龄相同按身高降序
array.sort((a, b) => {if (a.age !== b.age) {return a.age - b.age; // 年龄升序} else {return b.height - a.height; // 年龄相同,身高降序}
});console.log(array);

7. 使用稳定排序库(如 array-stable)

在某些情况下,你可能需要一个稳定的排序算法。JavaScript 的原生 sort() 方法在不同浏览器上可能不是稳定的。可以使用 array-stable 库来确保稳定排序。

安装该库:

npm install array-stable

使用示例:

const stable = require('array-stable'); // 导入稳定排序库const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];stable.sort(array, (a, b) => a.age - b.age); // 按年龄升序稳定排序
console.log(array);

8. 使用 Intl.Collator 进行本地化排序

对于字符串排序,特别是涉及到国际化时,可以使用 Intl.Collator 来处理。

const array = [{ name: 'Éclair', age: 25 },{ name: 'Alice', age: 22 },{ name: 'Bob', age: 30 }
];const collator = new Intl.Collator('fr', { sensitivity: 'base' }); // 创建法语语言环境的排序器
array.sort((a, b) => collator.compare(a.name, b.name)); // 按名称排序
console.log(array);

9. 使用 Proxy 对象包装数组

如果你希望在数组排序前后做一些额外操作,可以使用 Proxy 对象。

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];const handler = {set(target, property, value) {console.log(`Setting value ${value} on property ${property}`);target[property] = value;return true;}
};const proxyArray = new Proxy(array, handler); // 使用 Proxy 包装数组
proxyArray.sort((a, b) => a.age - b.age); // 对代理数组进行排序
console.log(proxyArray);

10. 使用 TypedArray 进行数值排序

如果数组中的对象包含大量数值,并且排序性能非常关键,可以考虑将数值提取到 TypedArray 中进行排序,然后映射回原数组。

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];const ages = new Uint8Array(array.map(item => item.age)); // 提取年龄到 Uint8Array 中
const sortedIndices = Array.from(ages).map((age, index) => ({ age, index })).sort((a, b) => a.age - b.age).map(item => item.index);const sortedArray = sortedIndices.map(index => array[index]); // 根据排序后的索引重构数组
console.log(sortedArray);

11. 按照对象属性值的字符串长度排序

const array = [{ name: 'Alice', description: 'A short description' },{ name: 'Bob', description: 'A very long and detailed description' },{ name: 'Charlie', description: 'Medium description' }
];// 按描述的长度升序排列
array.sort((a, b) => a.description.length - b.description.length);console.log(array);

12. 按照日期字段进行排序

const array = [{ event: 'Event 1', date: new Date('2023-05-01') },{ event: 'Event 2', date: new Date('2022-08-15') },{ event: 'Event 3', date: new Date('2024-01-10') }
];// 按日期升序排列
array.sort((a, b) => a.date - b.date);console.log(array);

13. 使用 reduce 和 Object.entries 对对象数组进行排序

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }
];// 使用 reduce 和 Object.entries 对对象数组按年龄升序排序
const sortedArray = Object.values(array.reduce((acc, obj) => {acc[obj.age] = obj;return acc;
}, {}));console.log(sortedArray);

14. 按照多个条件进行复杂排序

const array = [{ name: 'Alice', age: 25, height: 165 },{ name: 'Bob', age: 22, height: 175 },{ name: 'Charlie', age: 22, height: 170 },{ name: 'David', age: 22, height: 175 }
];// 按年龄升序,如果年龄相同,再按身高降序,如果年龄和身高都相同,再按姓名字母升序
array.sort((a, b) => {if (a.age !== b.age) {return a.age - b.age; // 年龄升序} else if (a.height !== b.height) {return b.height - a.height; // 身高降序} else {return a.name.localeCompare(b.name); // 姓名字母升序}
});console.log(array);

15. 基于对象某一属性的数值范围排序

const array = [{ name: 'Alice', score: 85 },{ name: 'Bob', score: 75 },{ name: 'Charlie', score: 95 },{ name: 'David', score: 80 }
];// 按分数区间排序:低于80分、80到90分之间、大于90分
array.sort((a, b) => {if (a.score < 80 && b.score >= 80) {return -1; // a 在 b 之前} else if (a.score >= 80 && a.score <= 90 && (b.score < 80 || b.score > 90)) {return -1; // a 在 b 之前} else if (a.score > 90 && b.score <= 90) {return 1; // a 在 b 之后} else {return 0;}
});console.log(array);

16. 使用 Map 进行自定义键排序

const array = [{ name: 'Alice', priority: 'medium' },{ name: 'Bob', priority: 'low' },{ name: 'Charlie', priority: 'high' },{ name: 'David', priority: 'medium' }
];const priorityOrder = new Map([['low', 1],['medium', 2],['high', 3]
]);// 按优先级排序
array.sort((a, b) => priorityOrder.get(a.priority) - priorityOrder.get(b.priority));console.log(array);

17. 按照嵌套对象属性排序

const array = [{ id: 1, details: { age: 25 } },{ id: 2, details: { age: 30 } },{ id: 3, details: { age: 20 } }
];// 按嵌套对象的年龄属性升序排序
array.sort((a, b) => a.details.age - b.details.age);console.log(array);

18. 按照字符串中的数字进行排序

const array = ['item20', 'item5', 'item12', 'item1'];// 按字符串中的数字部分进行升序排序
array.sort((a, b) => {const numA = parseInt(a.replace(/\D/g, ''));const numB = parseInt(b.replace(/\D/g, ''));return numA - numB;
});console.log(array);

19. 按照布尔值进行排序

const array = [{ name: 'Alice', isActive: true },{ name: 'Bob', isActive: false },{ name: 'Charlie', isActive: true },{ name: 'David', isActive: false }
];// 按布尔值排序,false 在前,true 在后
array.sort((a, b) => a.isActive - b.isActive);console.log(array);

20. 按照多个对象数组的属性组合排序

const array = [{ firstName: 'Alice', lastName: 'Smith' },{ firstName: 'Bob', lastName: 'Brown' },{ firstName: 'Charlie', lastName: 'Smith' },{ firstName: 'David', lastName: 'Johnson' }
];// 先按姓氏排序,如果姓氏相同,再按名字排序
array.sort((a, b) => {if (a.lastName !== b.lastName) {return a.lastName.localeCompare(b.lastName); // 按姓氏排序} else {return a.firstName.localeCompare(b.firstName); // 按名字排序}
});console.log(array);

21. 基于自定义权重排序

const array = [{ name: 'Alice', role: 'user' },{ name: 'Bob', role: 'admin' },{ name: 'Charlie', role: 'guest' },{ name: 'David', role: 'user' }
];const roleWeights = {'guest': 1,'user': 2,'admin': 3
};// 按角色权重排序
array.sort((a, b) => roleWeights[a.role] - roleWeights[b.role]);console.log(array);

22. 按照随机顺序排序

const array = [1, 2, 3, 4, 5];// 使用 Math.random() 将数组随机打乱
array.sort(() => Math.random() - 0.5);console.log(array);

23. 按照数组中对象的多个数值属性排序

const array = [{ name: 'Alice', score1: 90, score2: 85 },{ name: 'Bob', score1: 85, score2: 95 },{ name: 'Charlie', score1: 80, score2: 75 },{ name: 'David', score1: 90, score2: 80 }
];// 先按 score1 排序,如果 score1 相同,再按 score2 排序
array.sort((a, b) => {if (a.score1 !== b.score1) {return a.score1 - b.score1; // 按 score1 排序} else {return a.score2 - b.score2; // 按 score2 排序}
});console.log(array);

24. 按照对象属性的存在性排序

const array = [{ name: 'Alice', age: 25 },{ name: 'Bob' },{ name: 'Charlie', age: 30 },{ name: 'David' }
];// 有 age 属性的对象在前,没有的在后
array.sort((a, b) => ('age' in a ? -1 : 1) - ('age' in b ? -1 : 1));console.log(array);

这篇关于JavaScripts数组里的对象排序的24个方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088211

相关文章

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Pandas统计每行数据中的空值的方法示例

《Pandas统计每行数据中的空值的方法示例》处理缺失数据(NaN值)是一个非常常见的问题,本文主要介绍了Pandas统计每行数据中的空值的方法示例,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是空值?为什么要统计空值?准备工作创建示例数据统计每行空值数量进一步分析www.chinasem.cn处

Spring Boot中JSON数值溢出问题从报错到优雅解决办法

《SpringBoot中JSON数值溢出问题从报错到优雅解决办法》:本文主要介绍SpringBoot中JSON数值溢出问题从报错到优雅的解决办法,通过修改字段类型为Long、添加全局异常处理和... 目录一、问题背景:为什么我的接口突然报错了?二、为什么会发生这个错误?1. Java 数据类型的“容量”限制

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

SpringBoot请求参数接收控制指南分享

《SpringBoot请求参数接收控制指南分享》:本文主要介绍SpringBoot请求参数接收控制指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring Boot 请求参数接收控制指南1. 概述2. 有注解时参数接收方式对比3. 无注解时接收参数默认位置

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

SpringBoot项目中报错The field screenShot exceeds its maximum permitted size of 1048576 bytes.的问题及解决

《SpringBoot项目中报错ThefieldscreenShotexceedsitsmaximumpermittedsizeof1048576bytes.的问题及解决》这篇文章... 目录项目场景问题描述原因分析解决方案总结项目场景javascript提示:项目相关背景:项目场景:基于Spring

Spring Boot 整合 SSE的高级实践(Server-Sent Events)

《SpringBoot整合SSE的高级实践(Server-SentEvents)》SSE(Server-SentEvents)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实... 目录1、简述2、Spring Boot 中的SSE实现2.1 添加依赖2.2 实现后端接口2.3 配置超时时

Windows 上如果忘记了 MySQL 密码 重置密码的两种方法

《Windows上如果忘记了MySQL密码重置密码的两种方法》:本文主要介绍Windows上如果忘记了MySQL密码重置密码的两种方法,本文通过两种方法结合实例代码给大家介绍的非常详细,感... 目录方法 1:以跳过权限验证模式启动 mysql 并重置密码方法 2:使用 my.ini 文件的临时配置在 Wi

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二