2012-08-27 9 views
32

Was ist die beste Methode, um ein Sparse-Array zu sortieren und die Elemente auf den gleichen Indizes zu halten? Zum Beispiel:Javascript Sortierung Sparse Array Indizes beibehalten

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

Ich möchte nach der Art

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

Vielleicht mit den Schlüsselwörtern Google Sie könnten versuchen: 'Art', 'assoziatives Array', 'nach Wert', wenn ich verstehe dein Problem gut. – Ricola3D

Antwort

183

Hier zu haben ist ein Ansatz. Es kopiert die definierten Array-Elemente in ein neues Array und speichert ihre Indizes. Es sortiert das neue Array und fügt die sortierten Ergebnisse dann wieder in die zuvor verwendeten Indizes ein.

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); 
} 

Arbeits Demo: http://jsfiddle.net/jfriend00/3ank4/

+0

Funktioniert perfekt danke. – TestersGonnaTest

+0

@ jfriend000, was passiert, wenn ich '.sort()' direkt benutze? – Jashwant

+0

@Jashwant - Es verschiebt alle undefinierten Stellen im Array bis zum Ende und alle Werte nach vorne, was das OP nicht verlangt. Sie können das Ergebnis hier sehen: 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

Ich glaube nicht, dass das was ist Die Frage war wirklich gefragt – jfriend00

3

können Sie

  1. Verwenden filter oder Object.values ein Array mit den Werten Ihrer spärlichen Array zu erhalten.
  2. Dann sort dieses Array, von den größten zu kleineren. Beachten Sie, dass es nicht stabil ist, was besonders problematisch sein kann, wenn einige Werte nicht numerisch sind. Sie können Ihre eigene Sortierimplementierung verwenden.
  3. Verwenden Sie und pop, um das gewünschte Array zu erhalten. Weisen Sie es a zu.
var b = a.filter(function(x) { 
    return true; 
}).sort(function(x,y) { 
    return y - x; 
}); 
a = a.map([].pop, b); 

Oder in ECMAScript 2017

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

Die Variable "b" wird nicht in der ES5-Code benötigt, aber ich habe es verwendet, um den Code lesbarer zu machen. – Oriol

+1

Als Bonus ist das Original "a" unverändert Wenn Sie die 'map'-Rückgabe einer neuen Variablen zuweisen. Gute Arbeit, Oriol. Ich hasse es, dass "[] .sort" standardmäßig mutiert. – naomik

+0

Wenn wir davon ausgehen können, dass alle Elemente im Sparse-Array numerisch sind (und ohne diese Annahme würde sich der Sortier-Callback inkonsistent verhalten!), Können wir Elemente nur mit 'a.filter (() => true)' oder 'Object filtern .Werte (a) '. –

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 } 
]