如何基于另一个对象数组的name属性对对象数组排序(无需临时数组的单行实现方案)
按指定name顺序排序数组的单行实现方案
你提到的场景很常见——要根据一个数组的name顺序给另一个结构类似的数组排序,还要避免临时数组的单行写法,当然有办法实现!
先回顾你的原始数组:
const one = [ { id: 3, name: 'a'}, { id: 5, name: 'b'}, { id: 4, name: 'c'} ]; const two = [ { id: 7, name: 'b'}, { id: 6, name: 'c'}, { id: 2, name: 'a'} ];
方案1:直观版单行排序
这种写法最直接,在sort回调里直接对比元素name在one数组中的索引位置:
const sortedTwo = [...two].sort((a, b) => one.findIndex(item => item.name === a.name) - one.findIndex(item => item.name === b.name));
- 用
[...two]是为了不修改原数组two,如果不需要保留原数组,直接写two.sort(...)也可以。 findIndex会返回当前元素的name在one中的位置,通过索引差值让sort方法自动按照one的name顺序排列。
方案2:高性能版单行实现(推荐大数据量场景)
上面的方案每次排序对比都要调用findIndex,数组规模大的时候性能会受影响。可以先构建一个name到排序权重的映射表,再排序,也能封装成单行:
const sortedTwo = (nameOrder => [...two].sort((a, b) => nameOrder[a.name] - nameOrder[b.name]))(Object.fromEntries(one.map((item, idx) => [item.name, idx])));
这里用立即执行函数把映射表创建和排序逻辑打包在一起,既实现了单行写法,又把时间复杂度从O(n²)降到了O(n log n),适合数据量较大的场景。
注意事项
要确保两个数组的name值是完全一一对应的(没有缺失或多余的name),这样才不会出现索引为-1或者权重undefined的异常情况哦。
内容的提问来源于stack exchange,提问作者Bary
相关产品推荐
相关产品推荐

