Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript:排序数组并返回一个索引数组,该数组指示排序元素相对于原始元素的位置_Javascript_Indexing_Sorting - Fatal编程技术网

Javascript:排序数组并返回一个索引数组,该数组指示排序元素相对于原始元素的位置

Javascript:排序数组并返回一个索引数组,该数组指示排序元素相对于原始元素的位置,javascript,indexing,sorting,Javascript,Indexing,Sorting,假设我有一个Javascript数组,如下所示: var test = ['b', 'c', 'd', 'a']; 我想对数组进行排序。显然,我可以这样对数组进行排序: test.sort(); //Now test is ['a', 'b', 'c', 'd'] 但我真正想要的是一个索引数组,它指示排序元素相对于原始元素的位置。我不太清楚该如何表达,所以也许这就是为什么我在想怎么做时遇到困难的原因 如果这样一个方法被称为sortIndices(),那么我想要的是: var indices

假设我有一个Javascript数组,如下所示:

var test = ['b', 'c', 'd', 'a'];
我想对数组进行排序。显然,我可以这样对数组进行排序:

test.sort(); //Now test is ['a', 'b', 'c', 'd']
但我真正想要的是一个索引数组,它指示排序元素相对于原始元素的位置。我不太清楚该如何表达,所以也许这就是为什么我在想怎么做时遇到困难的原因

如果这样一个方法被称为sortIndices(),那么我想要的是:

var indices = test.sortIndices();
//At this point, I want indices to be [3, 0, 1, 2].
在原始数组中,“a”位于位置3,“b”位于位置0,“c”位于位置1,“d”位于位置2。因此,[3,0,1,2]

一种解决方案是对数组的副本进行排序,然后在排序后的数组中循环,找到每个元素在原始数组中的位置。但是,这感觉很笨拙


是否有一个现有的方法可以满足我的要求?如果没有,您将如何编写一个这样做的方法?

我将用数字0..n-1填充一个数组,并用比较函数对其排序

var test = ['b', 'c', 'd', 'a'];
var test_with_index = [];
for (var i in test) {
    test_with_index.push([test[i], i]);
}
test_with_index.sort(function(left, right) {
  return left[0] < right[0] ? -1 : 1;
});
var indexes = [];
test = [];
for (var j in test_with_index) {
    test.push(test_with_index[j][0]);
    indexes.push(test_with_index[j][1]);
}
function sortWithIndeces(toSort) {
  for (var i = 0; i < toSort.length; i++) {
    toSort[i] = [toSort[i], i];
  }
  toSort.sort(function(left, right) {
    return left[0] < right[0] ? -1 : 1;
  });
  toSort.sortIndices = [];
  for (var j = 0; j < toSort.length; j++) {
    toSort.sortIndices.push(toSort[j][1]);
    toSort[j] = toSort[j][0];
  }
  return toSort;
}

var test = ['b', 'c', 'd', 'a'];
sortWithIndeces(test);
alert(test.sortIndices.join(","));
var test = ['b', 'c', 'd', 'a'];
var len = test.length;
var indices = new Array(len);
for (var i = 0; i < len; ++i) indices[i] = i;
indices.sort(function (a, b) { return test[a] < test[b] ? -1 : test[a] > test[b] ? 1 : 0; });
console.log(indices);
var测试=['b','c','d','a'];
var len=测试长度;
var指数=新阵列(len);
对于(var i=0;itest[b]?1:0;});
控制台日志(索引);

Dave Aaron Smith是正确的,但是我认为在这里使用数组映射()很有趣


您可以使用es6(生成
0->N-1
索引数组并根据输入值对其进行排序)通过一行代码来实现这一点

var测试=['b','c','d','a']
var result=Array.from(数组(test.length.keys())
.sort((a,b)=>test[a]
这是克莱博伊斯答案的一个更为惯用的ES6版本,请参见他/她的评论:

return test.map((val, ind) => {return {ind, val}})
           .sort((a, b) => {return a.val > b.val ? 1 : a.val == b.val ? 0 : -1 })
           .map((obj) => obj.ind);

可以使用贴图对象执行此操作。只需将key/value设置为index/value,并使用Array.from将迭代器设置为二维数组,然后对索引、值或两者进行排序

function sorting(elements) {
  const myMap = new Map();
  elements.forEach((value, index) => {
    myMap.set(index, value);
  });
  const arrayWithOrderedIndexes = Array.from(myMap.entries()).sort((left, right) => {return left[1] < right[1] ? -1 : 1});
  myMap.clear();
  return arrayWithOrderedIndexes.map(elem => elem[0]);
}
const elements = ['value','some value','a value','zikas value','another value','something value','xtra value'];
sorting(elements);
函数排序(元素){
const myMap=新映射();
元素。forEach((值,索引)=>{
myMap.set(索引、值);
});
const arrayWithOrderedIndex=Array.from(myMap.entries()).sort((左、右)=>{return left[1]elem[0]);
}
常量元素=['value'、'some value'、'a value'、'zikas value'、'other value'、'something value'、'xtra value'];
分类(要素);
你可以做到


detailItems.slice()
.map((r,ix)=>{
r、 _ix=ix;
返回r;
})
.排序((a,b)=>{
…/*这里有一个..ix或b.ix*/
})

.slice()
克隆阵列以防止副作用:)

+1但我认为最好不要为..使用
。。在数组上的
循环中。这是个好主意。我会试试看。(我一开始就接受。)@Tomalak:我同意你关于。。在里面我在这方面遇到了很多问题。将
for in
与数组一起使用几乎总是一个非常糟糕的主意。请注意,如果数组未定义或为null,则可能会导致意外行为。这是我的补丁
Typescript函数getSortIndice(toSort:T[]):number[]{const sortingPair:[T,number][]=toSort.map((值,索引)=>[value,index]);sortingPair.sort((左,右)=>{return(左[0]| 0)<(右[0]| 0)?-1:1;//能够比较未定义的});const sortIndices:number[]=sortingPair.map([t,indice])=>indice);返回sortIndices;}
为什么不使用
。call
而不是
。apply
?因为它在字母表中的位置较晚:)老实说,没有真正的理由,在这种情况下使用call可能更有意义,因此,不需要每次都创建一个数组。将立即更新这很好,如果值相等,通过比较索引(a和b),它甚至可以更好一点(使排序稳定!)。即,更改
。。。测试[a]>测试[b]?1:0到
。。。测试[a]>测试[b]?1:a
,另请参见,它提供了一种(公认性能较差)在一行中填充数组的方法。扰流板:
let index=[…数组(test.length).keys()
.map返回一个新数组,因此不需要切片。这是最好的答案。使用Array.keys()不需要所有额外的映射和+1
var test = ['b', 'c', 'd', 'a'];
// make list with indices and values
indexedTest = test.map(function(e,i){return {ind: i, val: e}});
// sort index/value couples, based on values
indexedTest.sort(function(x, y){return x.val > y.val ? 1 : x.val == y.val ? 0 : -1});
// make list keeping only indices
indices = indexedTest.map(function(e){return e.ind});
var test = ['b', 'c', 'd', 'a']

var result = Array.from(Array(test.length).keys())
                  .sort((a, b) => test[a] < test[b] ? -1 : (test[b] < test[a]) | 0)
return test.map((val, ind) => {return {ind, val}})
           .sort((a, b) => {return a.val > b.val ? 1 : a.val == b.val ? 0 : -1 })
           .map((obj) => obj.ind);
function sorting(elements) {
  const myMap = new Map();
  elements.forEach((value, index) => {
    myMap.set(index, value);
  });
  const arrayWithOrderedIndexes = Array.from(myMap.entries()).sort((left, right) => {return left[1] < right[1] ? -1 : 1});
  myMap.clear();
  return arrayWithOrderedIndexes.map(elem => elem[0]);
}
const elements = ['value','some value','a value','zikas value','another value','something value','xtra value'];
sorting(elements);