2012-08-27 19 views
32

Jaka jest najlepsza metoda sortowania rzadkiej tablicy i utrzymywania elementów na tych samych indeksach? Na przykład:sortowanie javascript tablica zachowaj indeksy

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

Chciałbym po sortowania mieć

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

Być może można spróbować google ze słowami kluczowymi: 'rodzaju', 'asocjacyjnej', 'według wartości' Gdybym dobrze rozumiem swój problem. – Ricola3D

Odpowiedz

183

Oto jedno podejście. Kopiuje zdefiniowane elementy tablicy do nowej tablicy i zapisuje ich indeksy. Sortuje nową tablicę, a następnie umieszcza posortowane wyniki z powrotem w indeksach, które były wcześniej używane.

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

demo robocza: http://jsfiddle.net/jfriend00/3ank4/

+0

Działa doskonale dzięki. – TestersGonnaTest

+0

@ jfriend000, co jeśli użyję bezpośrednio '.sort()'? – Jashwant

+0

@Jashwant - Przesuwa wszystkie nieokreślone miejsca w tablicy do końca i wszystkie wartości z przodu, które nie są tym, o co prosił OP. Możesz zobaczyć rezultat tego tutaj: 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

Nie sądzę, to jest to, co pytanie naprawdę pytało: – jfriend00

3

Można

  1. Zastosowanie filter lub Object.values aby uzyskać tablicę z wartościami swojej rozrzedzony tablicy.
  2. Następnie sort tej tablicy, od największej do mniejszej. Należy pamiętać, że nie jest stabilny, co może być szczególnie problematyczne, jeśli niektóre wartości nie mają wartości numerycznych. Możesz użyć własnej implementacji sortowania.
  3. Użyj map i pop, aby uzyskać żądaną tablicę. Przypisać go do a.
var b = a.filter(function(x) { 
    return true; 
}).sort(function(x,y) { 
    return y - x; 
}); 
a = a.map([].pop, b); 

Albo w ECMAScript 2017,

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

Zmienna "b" nie jest potrzebna w kodzie ES5, ale użyłam go, aby kod był bardziej czytelny – Oriol

+1

Jako bonus, oryginalny "a" jest niezmodyfikowany jeśli przypisujemy powrót 'map' do nowej zmiennej. Dobra robota, Oriol. Nienawidzę, że '[] .sort' mutuje domyślnie. – naomik

+0

Jeśli możemy założyć, że wszystkie elementy w tablicy sparse są numeryczne (i bez tego założenia, to callback sortowania będzie zachowywał się niekonsekwentnie!), Wtedy możemy filtrować elementy tylko za pomocą 'a.filter (() => true)' lub 'Object .values ​​(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 } 
] 
Powiązane problemy