如何在JavaScript中根据另一个数组的元素对二维数组进行排序
根据指定数组顺序排序子数组的解决方案
我来帮你搞定这个排序问题!你的核心需求是让ArrayA的子数组按照ArrayB的元素顺序排列,本质上是根据子数组的第一个元素与ArrayB中元素的对应关系来排序。
首先先看你之前的错误代码:
ArrayA.sort((a, b) => ArrayB.indexOf(a.ArrayA) - ArrayB.indexOf(b.ArrayA));
问题出在a.ArrayA——这里的a是ArrayA里的子数组,它并没有ArrayA这个属性,你需要取子数组的第一个元素(也就是用来匹配ArrayB的键),也就是a[0]和b[0]。
方法一:直接修正sort回调(适合小数组)
如果你的数组长度不大,可以直接修改sort的回调函数,用子数组的第一个元素去ArrayB里找索引:
ArrayA.sort((a, b) => ArrayB.indexOf(a[0]) - ArrayB.indexOf(b[0]));
把你的示例代入测试,就能得到你想要的结果。不过要注意,Array.indexOf()每次都会遍历整个ArrayB,当数组元素很多时,这个方法的时间复杂度会达到O(n²),效率比较低。
方法二:创建映射表提升效率(推荐,支持任意长度数组)
对于任意长度的数组(只要两个数组长度一致,且ArrayA子数组的第一个元素都在ArrayB中),更高效的方式是先创建一个元素-索引映射表,这样查找索引的时间会降到O(1),整体排序复杂度为O(n log n),和sort本身的效率一致:
// 第一步:构建ArrayB的元素到索引的映射 const orderMap = {}; ArrayB.forEach((item, index) => { orderMap[item] = index; }); // 第二步:用映射表排序ArrayA ArrayA.sort((a, b) => orderMap[a[0]] - orderMap[b[0]]);
示例验证
把你的测试数据代入:
const ArrayA = [ ['1', '123', '321'], ['2', '456', '654'], ['3', '789', '987'], ['4', '420', '314'] ]; const ArrayB = ['2', '1', '4', '3']; const orderMap = {}; ArrayB.forEach((item, index) => { orderMap[item] = index; }); ArrayA.sort((a, b) => orderMap[a[0]] - orderMap[b[0]]); console.log(ArrayA); // 输出:[ ['2', '456', '654'], ['1', '123', '321'], ['4', '420', '314'], ['3', '789', '987'] ]
完全符合你的期望输出。
额外优化:处理不匹配的元素
如果ArrayA里存在子数组的第一个元素不在ArrayB中的情况,可以给这些元素设置默认排序位置(比如排到最后):
ArrayA.sort((a, b) => { // 不存在的元素默认索引设为无穷大,会被排到最后 const idxA = orderMap[a[0]] ?? Infinity; const idxB = orderMap[b[0]] ?? Infinity; return idxA - idxB; });
内容的提问来源于stack exchange,提问作者ChrisB
相关产品推荐
相关产品推荐

