web-dev-qa-db-fra.com

javascript sort tableau clairsemé garder les index

Quelle est la meilleure méthode pour trier un tableau fragmenté et conserver les éléments sur les mêmes index? Par exemple:

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

J'aimerais après le genre avoir

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

Voici une approche. Il copie les éléments de tableau définis dans un nouveau tableau et enregistre leurs index. Il trie le nouveau tableau, puis replace les résultats triés dans les index précédemment utilisés.

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

Démo de travail: http://jsfiddle.net/jfriend00/3ank4/

198
jfriend00

Vous pouvez

  1. Utilisez filter ou Object.values pour obtenir un tableau avec les valeurs de votre tableau épars.
  2. Alors sort ce tableau, du plus grand au plus petit. Sachez qu'il n'est pas stable, ce qui peut être particulièrement problématique si certaines valeurs ne sont pas numériques. Vous pouvez utiliser votre propre implémentation de tri.
  3. Utilisez map et pop pour obtenir le tableau souhaité. Attribuez-le à a.
var b = a.filter(function(x) {
    return true;
}).sort(function(x,y) {
    return y - x;
});
a = a.map([].pop, b);

Ou, dans ECMAScript 2017,

a = a.map([].pop, Object.values(a).sort((x,y) => y-x));
3
Oriol
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]
0
user1597524
// 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 }
]
0
happierall