如何在TypeScript中生成另一数组的排序索引数组(不修改原数组)
在TypeScript中获取数组的有序索引数组(不修改原数组)
作为从Delphi转过来的开发者,刚接触JS/TS确实会对数组操作有点懵,别担心,咱们一步步搞定这个需求——核心就是完全不改动原数组,得到原数组元素按从小到大排序后的索引数组。
首先先澄清你提到的array.sort()的问题:你说它会修改原数组,这点没错(因为JS的sort()是原地排序),但我们完全可以绕开这个问题——不对原数组调用sort,而是对一个单独的索引数组排序,排序的依据是原数组对应位置的元素值,这样原数组根本不会被碰。
具体思路拆解
- 生成初始索引数组:先创建一个和原数组长度相同的数组,里面装的是从0开始的连续索引。比如原数组长度是4,初始索引数组就是
[0,1,2,3],相当于给每个元素先“编个号”。 - 对索引数组按原数组元素排序:用
sort()对这个索引数组排序,但排序的规则不是比较索引本身,而是比较原数组中对应索引的元素大小。比如比较索引a和b时,看原数组[a]和原数组[b]谁大谁小,来决定a和b的顺序。 - 返回排序后的索引数组:这就是我们要的结果啦。
TypeScript代码实现
function getSortedIndices(arr: number[]): number[] { // 第一步:生成初始索引数组,每个元素对应原数组的索引 const indices = arr.map((_, index) => index); // 第二步:对索引数组排序,排序依据是原数组对应位置的元素值 indices.sort((a, b) => { // 从小到大排序:如果arr[a]更小,a排在前面 if (arr[a] < arr[b]) return -1; // 如果arr[a]更大,b排在前面 if (arr[a] > arr[b]) return 1; // 元素相等时,保持原索引顺序(稳定排序) return 0; }); return indices; }
验证你的示例
例1测试
const input1 = [5.3, 2.4, 4.5, 6.2]; const output1 = getSortedIndices(input1); console.log(output1); // 输出:[1, 2, 0, 3] console.log(input1); // 原数组完全不变:[5.3, 2.4, 4.5, 6.2]
例2测试
const input2 = [10, 11, 5, 34, 3, 7, 17]; const output2 = getSortedIndices(input2); console.log(output2); // 输出:[4, 2, 5, 0, 1, 6, 3] console.log(input2); // 原数组完全不变:[10, 11, 5, 34, 3, 7, 17]
额外说明
- 为什么原数组不会被修改?因为我们只操作了单独的
indices数组,原数组只是被用来读取元素值做比较,完全没有被修改的操作。 - 如果需要支持字符串等其他可比较类型,只需要把函数参数类型改成
Array<string | number>或者用泛型约束即可,比如:function getSortedIndices<T extends string | number>(arr: T[]): number[] { // 内部代码和上面一样 } - 现代浏览器和Node.js中的
sort()是稳定排序,所以当原数组中有相等元素时,它们的原始索引顺序会被保留,这点和Delphi中的排序逻辑是一致的。
内容的提问来源于stack exchange,提问作者Serginho
相关产品推荐
相关产品推荐

