Diziyi Javascript'te adına göre (alfabetik olarak) sırala


645

JavaScript kullanarak adıyla sıralamak için gereken bir dizi (dizideki bir nesne için aşağıya bakın) var. Nasıl yapabilirim?

var user = {
   bio: null,
   email:  "user@domain.com",
   firstname: "Anna",
   id: 318,
   lastAvatar: null,
   lastMessage: null,
   lastname: "Nickson",
   nickname: "anny"
};

Yanıtlar:


1066

Bir diziniz olduğunu varsayalım users. users.sortİki argüman alan bir işlevi kullanabilir ve iletebilir ve bunları karşılaştırabilirsiniz (karşılaştırıcı)

Geri dönmeli

  • ilk argüman ikiden küçükse negatif bir şey (sonuçtaki dizide ikinciden önce yerleştirilmelidir)
  • ilk argüman daha büyükse olumlu bir şey (ikincisinden sonra yerleştirilmelidir)
  • Eğer bu iki eleman eşitse.

Bizim durumumuzda iki unsur varsa ave bkarşılaştırmak istiyorsak a.firstnameveb.firstname

Misal:

users.sort(function(a, b){
    if(a.firstname < b.firstname) { return -1; }
    if(a.firstname > b.firstname) { return 1; }
    return 0;
})

Bu kod herhangi bir tür ile çalışacaktır.

"Gerçek hayat" ™ 'da sık sık yoksaymak, dizeleri karşılaştırırken aksan işaretleri, ß gibi garip sembolleri doğru sıralamak istediğinizi unutmayın, böylece kullanmak isteyebilirsiniz localeCompare. Açıklık için diğer cevaplara bakın.


5
Friggin müthiş ... Bir nodelisti kimliğe göre sıralıyorum ... çekicilik gibi çalışıyor Teşekkürler!
Cody

74
Daha sonraki bir tarihte gelenler için Mrchief'in cevabı daha iyidir çünkü büyük / küçük harfe duyarsızdır.
mlienau

25
Daha iyi ya da kötü demem. Bu sadece bir başka
RiaD

19
@RiaD yeterince adil. Sadece 'elma' öncesi listede 'Zebra' göründüğü, kasa dahil olmak üzere öğeleri alfabetik olarak sıralayan birçok durumu düşünemiyorum, çok yararlı olacaktır.
mlienau

15
Bu kod yalnızca İngilizce konuşulan ülkelerde çalışacaktır. Diğer ülkelerde ovunccetin'in cevabınılocaleCompare kullanmalısınız .
Spoike

543

ES6 ile mümkün olan en kısa kod!

users.sort((a, b) => a.firstname.localeCompare(b.firstname))

String.prototype.localeCompare () temel desteği evrenseldir!


27
2017'de yaşıyorsanız bugüne kadarki en iyi cevap
nathanbirrell

52
2018'de yaşıyorsanız da en iyi cevap;)
Simone

49
Muhtemelen 2019 için de en iyi cevap olacak.
Ahmad Maleki

23
2020 belki? ya da naaa?
kspearrin

15
ah adam, 2030'da dünya sular altında kalır ve bu sadece dağlarda çalışır.
Starfs

343

Bunun gibi bir şey:

array.sort(function(a, b){
 var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
 if (nameA < nameB) //sort string ascending
  return -1;
 if (nameA > nameB)
  return 1;
 return 0; //default return value (no sorting)
});

43
'ToLowerCase ()' dizelerini sıralarken çok önemlidir - büyük harfler sıralamanızı etkileyebilir.
MarzSocks

3
Başka birinin toLowerCase'in ne etkilediğini merak etmesi durumunda, çok fazla değil:'a'>'A' //true 'z'>'a' //true 'A'>'z' //false
SimplGy

14
@SimplGy Etkisinin kredi verdiğinizden biraz daha fazla olduğunu iddia ediyorum. Kabul edilen yanıt için yorumlarda belirtildiği gibi Örneğin, sizin sıralama işlevi dize sıralanır olsun veya olmasın bilmek önemlidir 'Zebra'dize daha yüksek 'apple'Kullanmadığınız eğer yapacağız .toLowerCase().
PrinceTyke

1
@ PrinceTyke evet bu iyi bir durum adamım. 'Z' < 'a' // trueve'z' < 'a' // false
SimplGy

2
Tüm geçerli noktalar ve ben sıralama her zaman "bağlıdır" bir şey olduğunu söyleyebilirim. İsimlere göre sıralıyorsanız, büyük / küçük harfe duyarlılık önemli olmayabilir. Diğer durumlarda olabilir. Ne olursa olsun, temel fikri elde ettikten sonra kişinin özel durumuna uyum sağlamanın zor olmadığını düşünüyorum.
Mrchief

336

Karşılaştırılan dizeler unicode karakterler içeriyorsa , sınıf localeCompareişleviniString aşağıdaki gibi kullanabilirsiniz :

users.sort(function(a,b){
    return a.firstname.localeCompare(b.firstname);
})

3
String.localeCompare Safari ve IE'yi desteklemiyor <11 :)
CORSAIR

13
@CORSAIR desteklenir, desteklenmeyen yalnızca ikinci ve üçüncü parametredir.
Codler

6
@CORSAIR bu örnekteki kullanım tüm büyük IE tarayıcılarda desteklenir: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… . LocaleCompare ayrıca büyük harf kullanımını da hesaba katar, bu yüzden bu uygulamanın en iyi uygulama olarak görülmesi gerektiğini düşünüyorum.
Matt Jensen

9
users.sort ((a, b) => a.firstname.localeCompare (b.firstname)) // Kısa n tatlı ES6 sürümü!
Nachiketha

4
tanklar kardeşim. ES6 kullanımdausers.sort((a, b) => a.name.localeCompare(b.name))
Mohmmad Ebrahimi Aval

32

Güzel küçük ES6 bir astar:

users.sort((a, b) => a.firstname !== b.firstname ? a.firstname < b.firstname ? -1 : 1 : 0);

2
Eşit değerleri düzgün işlemediğinden bu eksik.
Karl-Johan Sjögren

1
Tabii ki, bunu tespit ettiğiniz için teşekkürler, eşleşen değerler için bir kontrol ekledim
Sam Logan

fena değil Gerçekten hepsini bir satırda istiyorsanız, iç içe üçlüler okunabilirlik için olsa kafa karıştırıcı olsun
russter

24

LocaleCompare'i kullanabiliriz, ancak anahtar değerlerini de kontrol etmeliyiz

Bir girişte lname eksikse aşağıdaki kod çalışmaz.

obj.sort((a, b) => a.lname.localeCompare(b.lname))

Bu yüzden aşağıdaki gibi falsey değerini kontrol etmeliyiz

let obj=[
{name:'john',lname:'doe',address:'Alaska'},
{name:'tom',lname:'hopes',address:'California'},
{name:'harry',address:'Texas'}
]
let field='lname';
console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));

VEYA

biz lodash kullanabiliriz, bu çok basit. Döndürülen değerleri yani sayı veya dizeyi algılar ve buna göre sıralama yapar.

import sortBy from 'lodash/sortBy';
sortBy(obj,'name')

https://lodash.com/docs/4.17.5#sortBy


2
Lodash oldukça düzenli! Daha önce duymamıştım. Harika çalışıyor!
Derk Jan Speelman

15

underscorejs çok güzel _.sortBy işlevi sunar:

_.sortBy([{a:1},{a:3},{a:2}], "a")

veya özel bir sıralama işlevi kullanabilirsiniz:

_.sortBy([{a:"b"},{a:"c"},{a:"a"}], function(i) {return i.a.toLowerCase()})

2
ikinci örnek, dizeleri döndürmeyi içerir. sortByDöndürülen değerleri dize olarak algılar mı ve alfabetik sıralama yapar mı? Teşekkürler
superjos

12

İsimleri veya ñ veya áéíóú (İspanyolca'da ortak) gibi özel karakterlere sahip bir şey sıralıyorsak , yerel parametreler ( bu durumda ispanyolca için es ) ve bunun gibi seçenekleri kullanabiliriz:

let user = [{'firstname': 'Az'},{'firstname': 'Áb'},{'firstname':'ay'},{'firstname': 'Ña'},{'firstname': 'Nz'},{'firstname': 'ny'}];


user.sort((a, b) => a.firstname.localeCompare(b.firstname, 'es', {sensitivity: 'base'}))


console.log(user)

Resmi yerel seçenekler burada iana , es (İspanyolca), de (Almanca), fr (Fransızca) dilinde bulunabilir. Hakkında duyarlılık baz vasıtası:

Yalnızca temel harflerden farklı dizeler eşitsiz olarak karşılaştırılır. Örnekler: a ≠ b, a = á, a = A.


8

Temelde dizileri yöntem sıralamasıyla sıralayabilirsiniz, ancak nesneleri sıralamak istiyorsanız, dizi yöntemini sıralamak için işlevden geçmeniz gerekir, bu yüzden dizinizi kullanarak size bir örnek vereceğim

user = [{
bio: "<null>",
email: "user@domain.com",
firstname: 'Anna',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Senad',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Muhamed',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
}];

var ar = user.sort(function(a, b)
{
  var nA = a.firstname.toLowerCase();
  var nB = b.firstname.toLowerCase();

  if(nA < nB)
    return -1;
  else if(nA > nB)
    return 1;
 return 0;
});

neden sonunda 0'a geri dönelim?
Nobita

=, dizeler aynı olduğunda
Senad Meškin

ama bu durumda elsekaldırılmamalı mı? Aksi takdirde bu return 0asla okunmayacak
Nobita

2
bu "başka" değil, "başka" ise
Senad Meškin


8

Daha kompakt bir gösterim:

user.sort(function(a, b){
    return a.firstname === b.firstname ? 0 : a.firstname < b.firstname ? -1 : 1;
})

daha kompakt ancak sözleşmesini ihlal ediyor: sign(f(a, b)) =-sign(f(b, a))(a = b için)
RiaD

3
dönüş a.firstname == b.firstname===
tamlık

6

Ayrıca hem asec hem de desc sort için, bunu kullanabilirsiniz: varsayalım , artan sıralama veya azalan sıralama istediğiniz bir değişken SortType var:

 users.sort(function(a,b){
            return   sortType==="asc"? a.firstName.localeCompare( b.firstName): -( a.firstName.localeCompare(  b.firstName));
        })

5

Genelleştirilmiş bir fonksiyon aşağıdaki gibi yazılabilir

    function getSortedData(data, prop, isAsc) {
        return data.sort((a, b) => (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1));
   }

aşağıdaki parametreleri geçebilirsiniz

  1. Sıralamak istediğiniz veriler
  2. Verilerdeki mülkün sıralanması gerekir
  3. Son parametre boole tipindedir. Artan veya azalan şekilde sıralamak isteyip istemediğinizi kontrol eder

4

Deneyin

users.sort((a,b)=> (a.firstname>b.firstname)*2-1)


2
sıralama işlevi -1,0,1 döndürmelidir. bu sadece -1,1 döndürür.
Radu Luncasu

@RaduLuncasu - yukarıdaki çözümün yanlış sonuç verdiğini gösteren test verileri (kullanıcı dizisi) sağlayabilir misiniz? (bildiğim kadarıyla sıfır eksik sorun değil)
Kamil Kiełczewski

CompareFunction (a, b) 0 değerini döndürürse, a ve b öğelerini değişmeden bırakın, ancak tüm farklı öğelere göre sıralayın.
Radu Luncasu


@RaduLuncasu tamam, ancak bu bilgiler sıfırın zorunlu olduğu anlamına gelmez. Bunu göstermenin en iyi yolu, işe [9,8,7,6,5,1,2,3].sort((a,b) => a<b ? -1 : 1)
yaramayan

3

Bunu nesneler için kullanabilirsiniz

transform(array: any[], field: string): any[] {
return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);}

2

basitçe bu yöntemi kullanabilirsiniz

users.sort(function(a,b){return a.firstname < b.firstname ? -1 : 1});

1

Yerleşik dizi yöntemini - kullanabilirsiniz sort. Bu yöntem, geri arama yöntemini bir param olarak alır



    // custom sort function to be passed as param/callback to the Array's sort method
    function myCustomSort(a, b) {
        return (a.toLowerCase() > b.toLowerCase()) ? 1 : -1;
    }

    // Actual method to be called by entity that needs sorting feature
    function sortStrings() {
        var op = Array.prototype.sort.call(arguments, myCustomSort);
    }

    // Testing the implementation
    var sortedArray = sortStrings("Burger", "Mayo1", "Pizza", "boxes", "Apples", "Mayo");
    console.log(sortedArray); //["Apples", "boxes", "Burger", "Mayo", "Mayo1", "Pizza"]


Bu kodu anlamak için dikkat edilmesi gereken önemli noktalar.

  1. Özel yöntem, bu durumda, myCustomSorther öğe çifti (giriş dizisinden) karşılaştırması için +1 veya -1 döndürmelidir.
  2. Özel sıralama geri çağırma yönteminde toLowerCase()/ kullanın toUpperCase(), böylece büyük / küçük harf farkı sıralama işleminin doğruluğunu etkilemez.

Umarım bu yeterince açıklayıcıdır. Daha fazla bilgiye ihtiyaç olduğunu düşünüyorsanız yorum yapmaktan çekinmeyin.

Şerefe!


Doğru bir cevap değil, çünkü eşit kontrol yerine sadece çeklerden daha az ve daha fazla performans gösterir.
Steel Brain

Ayrıca ~ 2011'den beri orada oturan cevaplara kıyasla masaya yeni bir şey getirmiyor.
amenthes

1

En iyi cevapları tuşa göre sıralamak için bir prototipe itti.

Array.prototype.alphaSortByKey= function (key) {
    this.sort(function (a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    });
    return this;
};

0

Büyük / küçük harfe duyarlı olmak için benzer bir şey kullanabilirsiniz

users.sort(function(a, b){

  //compare two values
  if(a.firstname.toLowerCase() < b.firstname.toLowerCase()) return -1;
  if(a.firstname.toLowerCase() > b.firstname.toLowerCase()) return 1;
  return 0;

})

7
Mrchief'in cevabı ile aynı cevap. Diğer dezavantajla, toLowerCase'in karşılaştırma başına iki kez yerine dört kez yapılması.
amenthes

0

Uygulamam, eski ES sürümlerinde harika çalışıyor:

sortObject = function(data) {
    var keys = Object.keys(data);
    var result = {};

    keys.sort();

    for(var i = 0; i < keys.length; i++) {
        var key = keys[i];

        result[key] = data[key];
    }

    return result;
};

0

Yalnızca kayıt için, adlandırılmış bir sıralama işlevine sahip olmak istiyorsanız, sözdizimi aşağıdaki gibidir:

let sortFunction = (a, b) => {
 if(a.firstname < b.firstname) { return -1; }
 if(a.firstname > b.firstname) { return 1; }
 return 0;
})
users.sort(sortFunction)

Aşağıdakilerin çalışmadığını unutmayın:

users.sort(sortFunction(a,b))
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.