如何根据字符串或数组形式的自定义顺序对JavaScript对象数组排序
JavaScript对象数组自定义排序实现方案
需求说明
给定待排序数组:
var someAnswers = [ { answer: 'Lyndon Johnson', // answer A comment: '...' }, { answer: 'Richard Nixon', // answer B comment: '...' }, { answer: 'Jimmy Carter', // answer C comment: '...' }, { answer: 'Gerald Ford', // answer D comment: '...' } ];
自定义排序顺序支持两种输入格式:
// 逗号分隔字符串格式 customOrder = 'A, C, B, D'; // 数组格式 customOrder = ['A', 'C', 'B', 'D'];
期望按传入的自定义顺序对数组排序,例如传入'A, C, B, D'时输出顺序为A→C→B→D对应的对象,传入'D, B, A, C'时输出顺序为D→B→A→C对应的对象。
实现思路
- 先建立答案内容与排序标识(A/B/C/D)的映射关系,用于快速获取每个数组元素对应的排序标识
- 编写排序器生成函数,兼容字符串和数组两种自定义顺序输入格式
- 基于自定义顺序生成权重映射表,比较时直接通过权重值大小判断顺序,排序效率和原生sort方法一致
完整代码实现
// 建立答案到排序标识的映射 const answerLabelMap = { 'Lyndon Johnson': 'A', 'Richard Nixon': 'B', 'Jimmy Carter': 'C', 'Gerald Ford': 'D' }; /** * 生成自定义排序比较函数 * @param {string|Array} customOrder 自定义排序顺序,支持逗号分隔字符串或数组 * @returns {Function} 可直接传入Array.sort的比较函数 */ function getCustomSorter(customOrder) { // 兼容两种输入格式,统一转成数组 const orderList = typeof customOrder === 'string' ? customOrder.split(/\s*,\s*/) // 分割时自动去除逗号前后的空格 : [...customOrder]; // 生成标识到权重的映射,权重越小排序越靠前 const weightMap = {}; orderList.forEach((label, index) => { weightMap[label] = index; }); // 返回比较函数 return (a, b) => { const aLabel = answerLabelMap[a.answer]; const bLabel = answerLabelMap[b.answer]; return weightMap[aLabel] - weightMap[bLabel]; }; } // 可选:扩展数组原型实现更贴合需求的调用方式(不推荐生产环境污染原生原型) Array.prototype.sortByCustomOrder = function(customOrder) { return this.sort(getCustomSorter(customOrder)); };
使用示例
// 方式1:将生成的比较函数传入原生sort方法(推荐) const customOrder = 'A, C, B, D'; const sortedByACBD = someAnswers.sort(getCustomSorter(customOrder)); console.log(sortedByACBD); // 输出A→C→B→D顺序的数组 // 方式2:使用扩展的原型方法 const anotherCustomOrder = ['D', 'B', 'A', 'C']; const sortedByDBAC = someAnswers.sortByCustomOrder(anotherCustomOrder); console.log(sortedByDBAC); // 输出D→B→A→C顺序的数组
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

