如何对含关联字符串与子数组的数组按字符串排序并维持关联?
解决交替字符串-子数组的排序问题
你的问题核心是原数组的结构是字符串和对应子数组交替排列,直接用sort()会把所有元素混在一起比较,根本没法保证字符串和子数组的关联关系。咱们可以通过「打包成对 → 排序 → 展开」的三步法来解决:
具体步骤和代码实现
1. 先把交替元素打包成成对数组
首先遍历原数组,每两个元素(字符串+子数组)组成一个新的子数组,这样就能把关联关系牢牢绑定住:
let myArray = [ '789', ['111A','222B','333C'], '456', ['444E','555F','666G'], '123', ['777H','888I','999J'] ]; // 打包成 [字符串, 对应子数组] 的结构 const pairedArray = []; for (let i = 0; i < myArray.length; i += 2) { pairedArray.push([myArray[i], myArray[i + 1]]); }
此时pairedArray的结构是:
[ ['789', ['111A','222B','333C']], ['456', ['444E','555F','666G']], ['123', ['777H','888I','999J']] ]
2. 按字符串的数值大小排序
现在我们只需要对这个成对数组里的每一项,根据第一个元素(字符串)的数值来排序就行。因为你的字符串是纯数字,所以转成数字后比较更准确:
// 按字符串对应的数值升序排序 pairedArray.sort((pairA, pairB) => { return Number(pairA[0]) - Number(pairB[0]); });
排序后pairedArray就变成了:
[ ['123', ['777H','888I','999J']], ['456', ['444E','555F','666G']], ['789', ['111A','222B','333C']] ]
3. 展开成原来的一维数组结构
最后用flat()方法把成对数组展开成你需要的一维形式:
const sortedArray = pairedArray.flat(); console.log(sortedArray);
输出结果正好是你期望的:
['123', ['777H', '888I','999J'], '456', ['444E', '555F', '666G'], '789', ['111A', '222B', '333C']]
为什么原来的方法失效?
你之前用的myArray.sort(function(a,b){ return a - b })会失效,是因为当a或b是数组的时候,a - b会返回NaN(数组和数字无法直接做减法)。而sort()遇到NaN时会 fallback 到默认的排序规则(按元素的Unicode码点排序),自然没法得到你想要的结果。
扩展说明
如果你的字符串不是纯数字(比如包含字母),可以把排序逻辑换成字符串比较:
pairedArray.sort((pairA, pairB) => { return pairA[0].localeCompare(pairB[0]); });
这样就能按字符串的自然顺序排序啦。
内容的提问来源于stack exchange,提问作者Philyphil
相关产品推荐
相关产品推荐

