TypeScript bir diziyi sıralama


163

Daktilo ile karşılaştığım çok garip bir sorunu çözmeye çalışıyorum. Satır içi bir Boole ifadesini, tam ifade yerine ilk değerin türü olarak ele alıyordu.

Dolayısıyla, aşağıdaki gibi basit bir şey denerseniz:

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

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

Dene

Sıralama yönteminizde, sonuçlarınız Boole değil sayısal olduğundan parametrelerin çağrı hedefinin herhangi bir imzasıyla eşleşmediğini söyleyen bir hata alırsınız. Sanırım bir şeyi kaçırıyorum çünkü n1> n2'nin bir Boole ifadesi olduğundan oldukça eminim.

Yanıtlar:


189

Hata tamamen doğrudur.

Size anlatmaya çalıştığı gibi .sort(), boolean değil sayı döndüren bir işlev alır.

İlk öğe daha küçükse negatif döndürmeniz gerekir; daha büyükse pozitif, eşitse sıfır.


63
Bu yüzden TypeScript kullanıyoruz! :-)
Stephen Chung

238

Sayılar

Numaraları sıralarken, kompakt karşılaştırmayı kullanabilirsiniz:

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

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

yani -yerine <.

Diğer çeşitler

Başka bir şeyi karşılaştırıyorsanız, karşılaştırmayı bir sayıya dönüştürmeniz gerekir.

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

Nesneler

Nesneler için, bir özelliğe göre sıralama yapabilirsiniz, sayı türlerini kısaltmakla ilgili yukarıdaki bilgileri aklınızda bulundurun. Aşağıdaki örnek, türüne bakılmaksızın çalışır.

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

Bazıları, testten daha azı için 'Roy@my.net' in neden 'bob@my.net'ten daha az doğru döndürdüğünü açıklayabilir mi? örneğin: let myTest = ('Roy@my.net' <'bob@my.net'); // benim için true
değerini

1
ikinci durumda, geçerli yerel ayardaki dizeleri karşılaştırmak için localeCompare () kullanabilirsiniz, bu da bir sayı döndürür
neural5torm

Lütfen açıklayın, (n1,n2)=>n1-n2ifade nasıl uygulanacak veya çalışacak .. ??
Rahul Chaudhari

1
Sayı örneğindeki @RahulChaudhari, sayıları alan n1ve n2döndürdüğü işlev içinde n1-n2pozitif bir sayı, sıfır veya negatif bir sayı olacak bir işlevdir . Bu, sıralama işlemine öğelerin değiştirilmesinin gerekip gerekmediğini söyleyerek sıralamayı etkinleştirir.
Fenton

farklı özelliklere sahip filtre mümkün olabilir
Arvind

24

Harika cevap Sohnee. Bir dizi nesneniz varsa ve anahtara göre sıralamak istiyorsanız hemen hemen aynı olduğunu eklemek isteriz, bu, hem tarihe (sayı) hem de başlığa (dize) göre sıralayabilen bir örnektir:

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

İçerideki değerleri değişkenler n1 [alan] ve n2 [alan] olarak da yapabilir eğer daha dinamikse, dizeler ve sayılar arasındaki farkı koruyun.


Cevaplar hakkında yorum, yorumlar fonksiyonu kullanılarak yapılmalıdır.
Nicktar

6
@Nicktar Muhtemelen biçimlendirme için bir cevap olarak yayınlanmıştır. Ama yine de zararı yok
Wouter Vanherck

11

Karışık Diziyi Sıralama (harfler ve sayılar)

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)


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

Bazı alanlara göre sırala:

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

1
n1 - n2, n1 <n2 olduğunda negatif, n1> n2 olduğunda pozitif ve n1 == n2 olduğunda 0
Sébastien Stormacq

2
Teşekkürler! Bunu bunun için değiştirdim: myArray.sort ((a, b): number => {return a.NumberProp - b.NumberProp;});
Lrodriguez84


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)


Merhaba, stackoverflow'a hoş geldiniz, stackoverflow.com/help/how-to-answer lütfen bu belgeleri okuyun ve ne yapılması gerektiğine dair bazı açıklamalar sağlayın.
Prateik Darji

0

Bunu bugün _.sortByTypeScript'te yeniden oluşturmaya çalışırken yazdım ve ihtiyacı olan herkese bırakacağımı düşündüm.

// ** 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
    })
}

Kullanım:

Bir genel tip T dizisi bekler, dolayısıyla <T extends {}>çevirme, parametre ve işlev dönüş türünü yazmanın yanı sıraT[]

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

** getByKeyfn bulundu burada

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.