TypeScript sortiert ein Array

154

Ich habe versucht, ein sehr seltsames Problem herauszufinden, auf das ich mit Typoskript gestoßen bin. Es wurde ein boolescher Inline-Ausdruck als der Typ des ersten Werts anstelle des vollständigen Ausdrucks behandelt.

Wenn Sie also etwas Einfaches wie das Folgende ausprobieren:

var numericArray:Array<number> = [2,3,4,1,5,8,11];

var sorrtedArray:Array<number> = numericArray.sort((n1,n2)=> n1 > n2);

Versuch es

Bei Ihrer Sortiermethode wird eine Fehlermeldung angezeigt, dass die Parameter nicht mit der Signatur des Aufrufziels übereinstimmen, da Ihr Ergebnis numerisch und nicht boolesch ist. Ich vermisse wohl etwas, weil ich mir ziemlich sicher bin, dass n1> n2 eine boolesche Aussage ist.

Kent Cooper
quelle

Antworten:

180

Der Fehler ist völlig richtig.

Wie es Ihnen zu sagen versucht, .sort()nimmt eine Funktion, die Zahl zurückgibt, nicht boolesch.

Sie müssen ein negatives Ergebnis zurückgeben, wenn das erste Element kleiner ist. positiv, wenn es größer ist, oder null, wenn sie gleich sind.

SLaks
quelle
56
Deshalb verwenden wir TypeScript! :-)
Stephen Chung
225

Zahlen

Beim Sortieren von Zahlen können Sie den kompakten Vergleich verwenden:

var numericArray: number[] = [2, 3, 4, 1, 5, 8, 11];

var sortedArray: number[] = numericArray.sort((n1,n2) => n1 - n2);

dh -eher als <.

Andere Arten

Wenn Sie etwas anderes vergleichen, müssen Sie den Vergleich in eine Zahl umwandeln.

var stringArray: string[] = ['AB', 'Z', 'A', 'AC'];

var sortedArray: string[] = stringArray.sort((n1,n2) => {
    if (n1 > n2) {
        return 1;
    }

    if (n1 < n2) {
        return -1;
    }

    return 0;
});

Objekte

Bei Objekten können Sie nach einer Eigenschaft sortieren. Beachten Sie dabei die oben genannten Informationen zur Verwendung von Kurznummerntypen. Das folgende Beispiel funktioniert unabhängig vom Typ.

var objectArray: { age: number; }[] = [{ age: 10}, { age: 1 }, {age: 5}];

var sortedArray: { age: number; }[] = objectArray.sort((n1,n2) => {
    if (n1.age > n2.age) {
        return 1;
    }

    if (n1.age < n2.age) {
        return -1;
    }

    return 0;
});
Fenton
quelle
Könnte jemand erklären, warum '[email protected]' für den Test weniger als '[email protected]' true zurückgibt? zB: let myTest = ('[email protected]' <'[email protected]'); // gibt wahr für mich zurück ... :(
Wallace Howery
1
Im zweiten Fall können Sie localeCompare () verwenden, um Zeichenfolgen im aktuellen Gebietsschema zu vergleichen, das eine Zahl
zurückgibt
Bitte erklären Sie mir, wie (n1,n2)=>n1-n2Ausdruck ausgeführt wird oder funktioniert .. ??
Rahul Chaudhari
1
@RahulChaudhari im Zahlenbeispiel ist es eine Funktion, die die Zahlen nimmt n1und n2innerhalb der zurückgegebenen Funktion n1-n2entweder eine positive Zahl, eine Null oder eine negative Zahl ist. Dies teilt dem Sortiervorgang mit, ob die Elemente umgeschaltet werden müssen oder nicht, wodurch das Sortieren aktiviert wird.
Fenton
Es kann möglich sein, Filter mit unterschiedlichen Eigenschaften
Arvind
24

Tolle Antwort Sohnee. Wenn Sie ein Array von Objekten haben und nach Schlüssel sortieren möchten, ist dies fast dasselbe. Dies ist ein Beispiel für eines, das sowohl nach Datum (Nummer) als auch nach Titel (Zeichenfolge) sortiert werden kann:

    if (sortBy === 'date') {
        return n1.date - n2.date
    } else {
        if (n1.title > n2.title) {
           return 1;
        }
        if (n1.title < n2.title) {
            return -1;
        }
        return 0;
    }

Sie können die Werte auch als Variablen n1 [Feld] und n2 [Feld] festlegen, wenn sie dynamischer sind. Behalten Sie einfach den Unterschied zwischen Zeichenfolgen und Zahlen bei.

yairniz
quelle
Das Kommentieren von Antworten sollte mit der Kommentarfunktion erfolgen.
Nicktar
6
@Nicktar Es wird wahrscheinlich als Antwort auf die Formatierung veröffentlicht. Aber es schadet trotzdem nicht
Wouter Vanherck
11
let numericArray: number[] = [2, 3, 4, 1, 5, 8, 11];

let sortFn = (n1 , n2) => number { return n1 - n2; }

const sortedArray: number[] = numericArray.sort(sortFn);

Nach einem Feld sortieren:

let arr:{key:number}[] = [{key : 2}, {key : 3}, {key : 4}, {key : 1}, {key : 5}, {key : 8}, {key : 11}];

let sortFn2 = (obj1 , obj2) => {key:number} { return obj1.key - obj2.key; }

const sortedArray2:{key:number}[] = arr.sort(sortFn2);
Yoav Schniederman
quelle
1
n1 - n2 ist negativ, wenn n1 <n2, positiv, wenn n1> n2 und 0, wenn n1 == n2
Sébastien Stormacq
2
Vielen Dank! Ich habe es dafür geändert: myArray.sort ((a, b): number => {return a.NumberProp - b.NumberProp;});
Lrodriguez84
10

Mixed Array sortieren (Alphabete und Zahlen)

function naturalCompare(a, b) {
   var ax = [], bx = [];

   a.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });
   b.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });

   while (ax.length && bx.length) {
     var an = ax.shift();
     var bn = bx.shift();
     var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
     if (nn) return nn;
   }

   return ax.length - bx.length;
}

let builds = [ 
    { id: 1, name: 'Build 91'}, 
    { id: 2, name: 'Build 32' }, 
    { id: 3, name: 'Build 13' }, 
    { id: 4, name: 'Build 24' },
    { id: 5, name: 'Build 5' },
    { id: 6, name: 'Build 56' }
]

let sortedBuilds = builds.sort((n1, n2) => {
  return naturalCompare(n1.name, n2.name)
})

console.log('Sorted by name property')
console.log(sortedBuilds)

WasiF
quelle
Vielen Dank :)
Steve
6

Der einfachste Weg scheint darin zu bestehen, die zweite Zahl von der ersten zu subtrahieren:

var numericArray:Array<number> = [2,3,4,1,5,8,11];

var sorrtedArray:Array<number> = numericArray.sort((n1,n2) => n1 - n2);

https://alligator.io/js/array-sort-numbers/

Rafael Fraga Walter
quelle
0

function naturalCompare(a, b) {
   var ax = [], bx = [];

   a.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { ax.push([$1 || Infinity, $2 || ""]) });
   b.replace(/(\d+)|(\D+)/g, function (_, $1, $2) { bx.push([$1 || Infinity, $2 || ""]) });

   while (ax.length && bx.length) {
     var an = ax.shift();
     var bn = bx.shift();
     var nn = (an[0] - bn[0]) || an[1].localeCompare(bn[1]);
     if (nn) return nn;
   }

   return ax.length - bx.length;
}

let builds = [ 
    { id: 1, name: 'Build 91'}, 
    { id: 2, name: 'Build 32' }, 
    { id: 3, name: 'Build 13' }, 
    { id: 4, name: 'Build 24' },
    { id: 5, name: 'Build 5' },
    { id: 6, name: 'Build 56' }
]

let sortedBuilds = builds.sort((n1, n2) => {
  return naturalCompare(n1.name, n2.name)
})

console.log('Sorted by name property')
console.log(sortedBuilds)

Ashika
quelle
Hallo, Willkommen bei stackoverflow, stackoverflow.com/help/how-to-answer. Bitte lesen Sie diese Dokumentation und geben Sie eine Beschreibung, was zu tun ist.
Prateik Darji
0

Ich habe dieses heute geschrieben _.sortBy, als ich versuchte, es in TypeScript neu zu erstellen , und dachte, ich würde es jedem überlassen, der es braucht.

// ** Credits for getKeyValue at the bottom **
export const getKeyValue = <T extends {}, U extends keyof T>(key: U) => (obj: T) => obj[key] 

export const sortBy = <T extends {}>(index: string, list: T[]): T[] => {
    return list.sort((a, b): number => {
        const _a = getKeyValue<keyof T, T>(index)(a)
        const _b = getKeyValue<keyof T, T>(index)(b)
        if (_a < _b) return -1
        if (_a > _b) return 1
        return 0
    })
}

Verwendung:

Es erwartet ein Array vom generischen Typ T, daher die Umwandlung für <T extends {}>, sowie die Eingabe des Parameter- und Funktionsrückgabetyps mitT[]

const x = [{ label: 'anything' }, { label: 'goes'}]
const sorted = sortBy('label', x)

** getByKeyfn hier gefunden

Krake
quelle