Třídění pole v TypeScriptu
Snažil jsem se přijít na velmi podivný problém, na který jsem narazil u TypeScriptu. Choval se tak, že výraz typu Boolean zapsaný přímo v kódu považoval za typ prvního hodnoty, místo aby bral v úvahu celý výraz.
Takže pokud vyzkoušíte něco jednoduchého, například následující:
var numericArray:Array<number> = [2,3,4,1,5,8,11];
var sorrtedArray:Array<number> = numericArray.sort((n1,n2)=> n1 > n2);
TryIt
Zobrazí se vám chyba u metody řazení s tím, že parametry neodpovídají žádnému podpisu cílového volání, protože váš výsledek je číselný a ne Boolean. Myslím, že mi něco uniká, protože si docela jistě myslím, že n1>n2 je Boolean výraz.
Odpověď č. 1
Čísla
Při řazení čísel můžete použít kompaktní porovnání:
var numericArray: number[] = [2, 3, 4, 1, 5, 8, 11];
var sortedArray: number[] = numericArray.sort((n1,n2) => n1 - n2);
tj. - místo <.
Jiné typy
Pokud srovnáváte cokoli jiného, budete muset převést srovnání na číslo.
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;
});
Objekty
U objektů můžete řadit podle vlastnosti, mějte na paměti výše uvedené informace o možnosti zkráceného zápisu číselných typů. Níže uvedený příklad funguje bez ohledu na 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;
});
Odpověď č. 2
Chyba je naprosto správná.
Jak se vám snaží naznačit, .sort() bere funkci, která vrací číslo, ne boolean.
Musíte vrátit záporné číslo, pokud je první položka menší; kladné, pokud je větší, nebo nulu, pokud jsou stejné.
Odpověď č. 3
Skvělá odpověď, Sohnee. Chtěl bych dodat, že pokud máte pole objektů a chcete ho třídit podle klíče, je to téměř stejné, toto je příklad jednoho, který může třídit jak podle data (číslo), tak podle názvu (řetězec):
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;
}
Také byste mohli hodnoty uvnitř udělat jako proměnné n1[field] vs n2[field], pokud je to dynamičtější, jen zachovejte rozdíl mezi řetězci a čísly.
Odpověď č. 4
let numericArray: number[] = [2, 3, 4, 1, 5, 8, 11];
let sortFn = (n1 , n2) => number { return n1 - n2; }
const sortedArray: number[] = numericArray.sort(sortFn);
Seřadit podle nějakého pole:
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);
Odpověď č. 5
Seřadit smíšené pole (písmena a čísla)
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)Odpověď č. 6
Nejjednodušší způsob se zdá být odečtení druhého čísla od prvního:
var numericArray:Array<number> = [2,3,4,1,5,8,11];
var sortedArray:Array<number> = numericArray.sort((n1,n2) => n1 - n2);
https://alligator.io/js/array-sort-numbers/
