2012-08-27 74 views
32

什麼是排序稀疏數組並保持相同索引上的元素的最佳方法? 例如:javascript排序稀疏數組保持索引

a[0] = 3, 
a[1] = 2, 
a[2] = 6, 
a[7] = 4, 
a[8] = 5, 

我想之後的排序有

a[0] = 2, 
a[1] = 3, 
a[2] = 4, 
a[7] = 5, 
a[8] = 6. 
+0

也許你可以嘗試用關鍵詞來谷歌: '排序', '關聯數組', '按值' 如果我很好地理解你的問題。 – Ricola3D

回答

183

這裏有一個方法。它將定義的數組元素複製到一個新數組並保存其索引。它對新數組進行排序,然後將排序結果放回到以前使用的索引中。

var a = []; 
a[0] = 3; 
a[1] = 2; 
a[2] = 6; 
a[7] = 4; 
a[8] = 5; 


// sortFn is optional array sort callback function, 
// defaults to numeric sort if not passed 
function sortSparseArray(arr, sortFn) { 
    var tempArr = [], indexes = []; 
    for (var i = 0; i < arr.length; i++) { 
     // find all array elements that are not undefined 
     if (arr[i] !== undefined) { 
      tempArr.push(arr[i]); // save value 
      indexes.push(i);   // save index 
     } 
    } 
    // sort values (numeric sort by default) 
    if (!sortFn) { 
     sortFn = function(a,b) { 
      return(a - b); 
     } 
    } 
    tempArr.sort(sortFn); 
    // put sorted values back into the indexes in the original array that were used 
    for (var i = 0; i < indexes.length; i++) { 
     arr[indexes[i]] = tempArr[i]; 
    } 
    return(arr); 
} 

工作演示:http://jsfiddle.net/jfriend00/3ank4/

+0

完美謝謝。 – TestersGonnaTest

+0

@ jfriend000,如果我直接使用'.sort()'怎麼辦? – Jashwant

+0

@Jashwant - 它推動數組中所有未定義的點到最後,所有的值都到達前面,這不是OP所要求的。你可以看到在這裏的結果:http://jsfiddle.net/jfriend00/UteW2/ – jfriend00

0
var arr = [1,2,3,4,5,6,7,8,9,10]; 
// functions sort 
function sIncrease(i, ii) { // ascending 
if (i > ii) 
return 1; 
else if (i < ii) 
return -1; 
else 
return 0; 
} 
function sDecrease(i, ii) { //descending 
if (i > ii) 
return -1; 
else if (i < ii) 
return 1; 
else 
return 0; 
} 
function sRand() { // random 
return Math.random() > 0.5 ? 1 : -1; 
} 
arr.sort(sIncrease); // return [1,2,3,4,5,6,7,8,9,10] 
arr.sort(sDecrease); // return [10,9,8,7,6,5,4,3,2,1] 
arr.sort(sRand); // return random array for examle [1,10,3,4,8,6,9,2,7,5] 
+3

我不認爲這是什麼問題真的在問 – jfriend00

3

可以

  1. 使用filterObject.values以獲得與您的稀疏數組的值的數組。
  2. 然後sort那個數組,從大到小。請注意它不穩定,如果某些值不是數字,這可能會特別有問題。您可以使用自己的排序實現。
  3. 使用mappop來獲得所需的陣列。將其分配給a
var b = a.filter(function(x) { 
    return true; 
}).sort(function(x,y) { 
    return y - x; 
}); 
a = a.map([].pop, b); 

或者,在ECMAScript中2017年,

a = a.map([].pop, Object.values(a).sort((x,y) => y-x)); 
+0

ES5代碼中不需要變量'b',但是我用它來使代碼更具可讀性 – Oriol

+1

作爲獎勵,原始的'a'是未修改的如果賦值'map'返回一個新的變量。好的工作,Oriol。我討厭''[] .sort'默認情況下會發生變異。 – naomik

+0

如果我們可以假設稀疏數組中的所有元素都是數值的(並且沒有這種假設,那麼排序回調會表現得不一致!),那麼我們可以用'a.filter((=)=> true')或'Object .values(一)'。 –

0
// Update for your needs ('position' to your key). 

function updateIndexes(list) { 

    list.sort((a, b) => a.position - b.position) 

    list.forEach((_, index, arr) => { 

     arr[ index ].position = index 

    }) 

} 

var myList = [ 
    { position: 8 }, 
    { position: 5 }, 
    { position: 1 }, 
    { position: 9 } 
] 

updateIndexes(myList) 

// Result: 

var myList = [ 
    { position: 1 }, 
    { position: 2 }, 
    { position: 3 }, 
    { position: 4 } 
]