如何在ECMAScript 5中对数组筛选子集排序并保留原数组结构?
需求:对数组筛选子集排序后保留原数组其他元素位置
原数组如下:
var data = [ { name: "Cccc", sortCriteria: 1 }, { name: "Bbbb", sortCriteria: 1 }, { name: "Dddd", sortCriteria: 0 }, { name: "Eeee", sortCriteria: 1 }, { name: "Ffff", sortCriteria: 0 }, ];
需要实现:仅对sortCriteria为1的元素按name(不区分大小写)排序,同时保持sortCriteria为0的元素在原数组中的位置不变,最终得到完整数组,预期输出的name顺序为:
Bbbb Cccc Dddd Eeee Ffff
要求使用ECMAScript 5实现,注意相关问题的部分解决方案不符合ES5规范,无法满足需求。
解决方案
核心思路:提取并排序符合条件的子集,再遍历原数组将排序后的元素依次填充到对应位置,保留不符合条件元素的原位置。
// 1. 筛选出sortCriteria为1的元素,复制后排序(避免原地排序影响原筛选结果) var sortedSubset = data.filter(function(item) { return item.sortCriteria === 1; }).slice().sort(function(a, b) { var aName = a.name.toLowerCase(); var bName = b.name.toLowerCase(); if (aName < bName) return -1; if (aName > bName) return 1; return 0; }); // 2. 遍历原数组,替换排序后的元素 var result = data.map(function(item) { if (item.sortCriteria === 1) { // 取出排序后子集的首个元素,保证顺序匹配 return sortedSubset.shift(); } // 不符合条件的元素直接保留原位置 return item; }); // 输出验证 result.forEach(function(item) { console.log(item.name); });
代码说明:
- 使用
slice()复制筛选数组:因为Array.sort()是原地排序方法,复制后排序不会修改原筛选结果 map()遍历原数组:遇到符合条件的元素时,从排序后的子集中按顺序取出元素替换,确保排序后的元素填充到原数组的对应位置- 所有语法均符合ECMAScript 5规范,未使用ES6及以上特性
内容的提问来源于stack exchange,提问作者Sebastien Chemouny
相关产品推荐
相关产品推荐

