Ich habe eine Reihe von Zeichenfolgen, die ich sortieren muss:

['1.2.3', '1.5.2', '1.23', '1.20.31']

Ist es möglich, das Array so zu sortieren, dass wir nach dem Teilen eines Strings durch den Punkt wie 1.2.3 in ['1','2', '3'] einen Positionsvergleich mit einem anderen Array durchführen (wie Python-Tupelvergleich)?

Erwartetes Ergebnis

['1.2.3', '1.5.2' '1.20.31', '1.23']

Ich weiß, dass es mit nativem JavaScript .sort mit Vergleichsfunktion für 2 Objekte möglich ist, aber ich kann die JS-Sortierung nicht verwenden, da ich das ursprüngliche Array nicht ändern kann. Ist es möglich, Lodashs _.sortBy zu verwenden, von dem erwartet wird, dass Sie eine Schlüsselfunktion geben?

1
petabyte 12 Aug. 2015 im 20:47

3 Antworten

Beste Antwort

Lösung mit Vanilla.js:

var data = ['1.2.3', '1.5.2', '1.23', '1.20.31'];

function customSort(d) {
    return d.map(function (a) {
        return a.split('.').map(Number);
    }).sort(function (a, b) {
        var l = 0, m = Math.min(a.length, b.length);
        while (l < m && a[l] === b[l]) {
            l++;
        }
        return l === m ? a.length - b.length : a[l] - b[l];
    }).map(function (a) {
        return a.join('.');
    });
}

document.write('<pre>sorted array ' + JSON.stringify(customSort(data), 0, 4) + '</pre>');
document.write('<pre>original array ' + JSON.stringify(data, 0, 4) + '</pre>');
2
Nina Scholz 13 Aug. 2015 im 06:05

ES5 + Lodash

var data = ['1.2.3', '1.5.2', '1.23', '1.20.31'];
var sortedData = _.sortBy(data, function(x){ return
                   x.split('.')
                    .map(function(i){ return 
                       _.padLeft(i, 5, '0'); })
                    .join('');
                 }));

ES6 + Lodash

var data = ['1.2.3', '1.5.2', '1.23', '1.20.31'];
var sorteddData = _.sortBy(data, x =>
                    x.split('.')
                     .map(i => _.padLeft(i, 5, '0'))
                     .join('')
                    );
1
Vitaliy Tsvayer 12 Aug. 2015 im 22:13

Sie können sortByAll () verwenden, um komplexe Sortierungen wie folgt durchzuführen:

var arr = ['1.2.3', '1.5.2', '1.23', '1.20.31', '1.20.29'];

function splitNumber(index, str) {
    return parseInt(_.get(str.split('.'), index, 0));
}

_.sortByAll(
    arr,
    _.partial(splitNumber, 0),
    _.partial(splitNumber, 1),
    _.partial(splitNumber, 2)
);
// → ["1.2.3", "1.5.2", "1.20.29", "1.20.31", "1.23"]

Die Funktion splitNumber() ruft das Element aus einer Zeichenfolge, nach der sortiert werden soll, als Ganzzahl ab. Dann verwenden wir Partial (), um die 3 Iterate für sortByAll() zu erstellen.

1
Adam Boduch 12 Aug. 2015 im 19:38