41 Soru: Nesnelerin dizesini string özellik değerine göre sıralama

tarafından oluşturulan soru Mon, Oct 8, 2018 12:00 AM

Bir dizi JavaScript nesnem var:

 
var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Onları JavaScript'teki last_nom değerine göre nasıl sıralayabilirim?

sort(a,b)'u biliyorum, ancak bu yalnızca karakter dizileri ve sayılar üzerinde çalışıyor gibi görünüyor. Nesnelerime toString() yöntemi eklemem gerekir mi?

    
2332
  1. Bu komut dosyası, kendi karşılaştırma işlevinizi veya sıralayıcınızı yazmak istemediğiniz sürece, tam da bunu yapmanızı sağlar: thomasfrank.se/sorting_things.html
    2009-07-15 03: 31: 47Z
30 Yanıtlar                              30                         

Kendi karşılaştırma işlevinizi yazmak yeterince kolaydır:

 
function compare( a, b ) {
  if ( a.last_nom < b.last_nom ){
    return -1;
  }
  if ( a.last_nom > b.last_nom ){
    return 1;
  }
  return 0;
}

objs.sort( compare );

Veya satır içi (Marco Demaio) /:  

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0)); 
    
3376
2019-04-21 14: 30: 29Z
  1. Veya satır içi: objs.sort (function (a, b) {return (a.last_nom > b.last_nom)? 1: ((b.last_nom > a.last_nom) -1 -1: 0);});
    2010-02-24 18: 29: 10Z
  2. 2012-05-18 09: 11: 15Z
  3. return a.last_nom.localeCompare(b.last_nom) da işe yarayacak.
    2013-02-14 10: 37: 20Z
  4. alanın sayısal olduğu bir sıralama arayanlar için, karşılaştırma işlevi gövdesi: return a.value - b.value; (ASC)
    2014-01-08 12: 06: 25Z
  5. @ Cerbrus localeCompare, yabancı dillerde vurgulu karakterler kullanırken önemlidir ve aynı zamanda daha da zariftir.
    2016-06-01 16: 38: 05Z

Ayrıca, nesneleri ilettiğiniz değerine göre sıralayan dinamik bir sıralama işlevi de oluşturabilirsiniz:

 
function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        /* next line works with strings and numbers, 
         * and you may want to customize it to your needs
         */
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

Böylece bunun gibi bir dizi nesneye sahip olabilirsiniz:

 
var People = [
    {Name: "Name", Surname: "Surname"},
    {Name:"AAA", Surname:"ZZZ"},
    {Name: "Name", Surname: "AAA"}
];

... ve yaptığınız zaman çalışacaktır:

 
People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));

Aslında bu zaten soruyu cevaplıyor. Aşağıda, çoğu kişi benimle iletişim kurduğundan, birden fazla parametreyle çalışmadığından şikayet ettiğinden, yazının altındaki kısmı yazılmıştır.

Birden Çok Parametre

Birden çok sıralama parametresi içeren sıralama işlevleri oluşturmak için aşağıdaki işlevi kullanabilirsiniz.

 
function dynamicSortMultiple() {
    /*
     * save the arguments object as it will be overwritten
     * note that arguments object is an array-like object
     * consisting of the names of the properties to sort by
     */
    var props = arguments;
    return function (obj1, obj2) {
        var i = 0, result = 0, numberOfProperties = props.length;
        /* try getting a different result from 0 (equal)
         * as long as we have extra properties to compare
         */
        while(result === 0 && i < numberOfProperties) {
            result = dynamicSort(props[i])(obj1, obj2);
            i++;
        }
        return result;
    }
}

Hangisi böyle bir şey yapmanıza izin verir:

 
People.sort(dynamicSortMultiple("Name", "-Surname"));

Alt Sınıflama Dizisi

Aramızdaki, yerel nesnelerin genişletilmesine izin veren ES6’yı kullanabilen şanslı insanlar için:

 
class MyArray extends Array {
    sortBy(...args) {
        return this.sort(dynamicSortMultiple.apply(null, args));
    }
}

Bu, bunu etkinleştirir:

 
MyArray.from(People).sortBy("Name", "-Surname");
    
756
2019-05-18 15: 09: 53Z
  1. Lütfen, JavaScript’teki özellik adlarının herhangi bir dize olabileceğini ve "-" ile başlayan özellikleriniz varsa (çok düşük olasılıkla ve muhtemelen değil) unutmayın. iyi bir fikir), ters sıralama göstergesi olarak başka bir şeyi kullanmak için dynamicSort işlevini değiştirmeniz gerekir.
    2013-01-10 15: 18: 39Z
  2. Yukarıdaki örnekteki dynamicSort()'un küçük harflerin önüne büyük harfler koyacağını fark ettim. Örneğin, APd, Aklin ve AbeASC sıralamasındaki sonuçların Abe, Aklin, APd olması gerekir. Ancak, örneğin, sonuçlar APd, Abe, Aklin. Yine de bu davranışı düzeltmek için?
    2017-07-26 22: 06: 50Z
  3. @ LloydBanks, bunu kesinlikle dizeler için kullanıyorsanız, var result = a[property].localeCompare(b[property]); yerine var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; kullanabilirsiniz.
    2017-08-06 08: 55: 17Z
  4. Tıpkı bir cevap gibi, undefine özelliklerinin olduğu durumlarda bu başarısız olur: [ { a: 5 }, {a:2}, {}, {a:1} ]
    2018-01-19 04: 09: 11Z
  5. @ EgeÖzcan Üst ya da alta öğeleri koymalı, işte pastebin.com/g4dt23jU
    2018-01-20 00: 37: 17Z

ES6 /ES2015 veya sonraki sürümlerinde bu şekilde yapabilirsiniz:

 
objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));
    
267
2016-01-29 19: 44: 37Z
  1. bu, JS 1.1'den beri kullanıldı, bunun için şişman ok parçası ES6 /2015 parçası. Ama yine de çok yararlı ve bence en iyi cevap
    2016-02-22 20: 30: 59Z
  2. @ PratikKelwalkar: tersine çevirmeniz gerekirse, sadece a ve b karşılaştırmasını değiştirin: objs.sort ((a, b) = > b.last_nom.localeCompare (a. last_nom));
    2016-05-26 18: 24: 21Z
  3. , sıralama alanını adreslemek için de bir dizin kullanmak mümkündür: last_nom yerine, dizideki sayıyı kullanın: 1?
    2017-05-29 18: 15: 52Z
  4. @ VladBezden, cevabınız için teşekkürler! Bu çözüm, çok küçük bir programlı çabayla ve doğru sıralama sonuçlarıyla ve şöyle bir dize dizisi olan ilk çözümdür: ["Ad1", "Ad10", "Ad2", "başka bir şey", "Ad11"]. objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom, undefined, {numberic: true})); ile doğru çalışmak için sıralama yaptım
    2018-01-09 08: 49: 39Z
  5. Bunu azalan sayılarla yapmak için: .sort ((a, b) = > b.numberProperty - a.numberProperty). Artan: .sort ((a, b) = > a.numberProperty - b.numberProperty)
    2019-05-23 05: 05: 58Z

underscore.js

alt çizgi kullanın, küçük ve harika ...

  

sortBy_.sortBy (list, yineleyici, [bağlam]) Sıralı bir kopyasını döndürür   Her bir değerin çalıştırılmasının sonuçlarına göre artan sırada sıralanmış liste   yineleyici aracılığıyla. Yineleyici, özelliğin dize adı da olabilir.   sıralamak için (örneğin, uzunluk).

 
var objs = [ 
  { first_nom: 'Lazslo',last_nom: 'Jamf' },
  { first_nom: 'Pig', last_nom: 'Bodine'  },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortedObjs = _.sortBy( objs, 'first_nom' );
    
174
2016-03-10 19: 34: 40Z
  1. David, var sortedObjs = _.sortBy( objs, 'first_nom' ); diyerek cevabını düzenleyebilir misiniz? objs, bunun sonucu olarak sıralanmayacak . İşlev, sıralanmış bir diziyi döndürür . Bu daha açık hale getirir.
    2014-01-09 04: 01: 06Z
  2. Sıralamayı tersine çevirmek için: var reverseSortedObjs = _.sortBy( objs, 'first_nom' ).reverse();
    2016-01-31 10: 43: 07Z
  3. javascript kütüphanesini "underscore" yüklemeniz gerekiyor: <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"> </script>
    2017-05-29 18: 28: 54Z
  4. Bunu tercih edenler için Lodash adresinde de bulunabilir
    2018-04-17 10: 49: 32Z
  5. Lodash'ta bu aynı olur: var sortedObjs = _.sortBy( objs, 'first_nom' ); veya farklı bir düzende istiyorsanız: var sortedObjs = _.orderBy( objs, ['first_nom'],['dsc'] );
    2018-11-15 19: 10: 03Z

İnsanların neden bu kadar karmaşık hale geldiğini anlama:

 
objs.sort(function(a, b){
  return a.last_nom > b.last_nom;
});

Daha sert motorlar için:

 
objs.sort(function(a, b){
  return a.last_nom == b.last_nom ? 0 : +(a.last_nom > b.last_nom) || -1;
});

İşleci, ters alfabetik sıraya göre sıralamak için değiştirin.

    
164
2014-04-22 19: 25: 59Z
  1. Sıralamada kullanılan işlev -1, 0 veya 1 döndürmesi gerektiğinden bu doğru değildir, ancak yukarıdaki işlev bir boolean döndürür. Sıralama kromda iyi çalışıyor ancak mesela PhantomJS'de başarısız oluyor. code.google.com/p/phantomjs/issues/detail?id adresine bakın. = 1090
    2014-04-22 15: 05: 30Z
  2. Bazı motorlar aptallığı hesaba katar, bu şekilde bir istismar vardı. Cevabımı uygun bir sürümle güncelledim.
    2014-04-22 19: 23: 15Z
  3. İlk sürümü almak için düzenlemeyi öneririm. Daha özlü olduğu için daha çekici görünüyor, ama işe yaramıyor, en azından güvenilir değil. Birisi bir tarayıcıda denerse ve çalışırsa, bir sorunu olduğunu bile fark etmeyebilir (özellikle yorumları okumamışsa). İkinci sürüm düzgün çalışıyor, bu yüzden ilkine gerçekten gerek yok.
    2016-03-11 15: 01: 39Z
  4. @ Simon İlk önce "biraz yanlış" sürümüne sahip olduğum için gerçekten minnettarım, çünkü daha katı uygulamanın ayrıştırılması ve anlaşılması birkaç saniye sürüyor ve onsuz daha zor olacak.
    2016-06-24 16: 50: 45Z
  5. @ Lion789 bunu yapın: if(a.count == b.count) return a.name > b.name; else return a.count > b.count;
    2017-05-07 17: 16: 53Z

Soyadları yinelenen adlarınız varsa, bunları adlarına göre sıralayabilirsiniz-

 
obj.sort(function(a,b){
  if(a.last_nom< b.last_nom) return -1;
  if(a.last_nom >b.last_nom) return 1;
  if(a.first_nom< b.first_nom) return -1;
  if(a.first_nom >b.first_nom) return 1;
  return 0;
});
    
61
2014-04-29 18: 35: 50Z
  1. Bu a< b a >b formatlama ilginç.
    2016-01-26 01: 51: 09Z
  2. @ BadFeelingAboutBu -1 veya 1 değerini döndürmenin anlamı nedir? Anladığım kadarıyla anlamıyla -1, sadece sözdiziminde A'nın B'den daha az olduğu anlamına gelir, ancak neden 1 veya -1 kullanıyorsunuz? Herkesin bu sayıları dönüş değerleri olarak kullandığını görüyorum ama neden? Teşekkürler.
    2018-08-22 06: 15: 00Z
  3. @ Chris22, negatif bir sayı döndürdü, b'un dizide a'dan sonra gelmesi gerektiği anlamına gelir. Pozitif bir sayı döndürülürse, a'dan sonra b'un gelmesi gerektiği anlamına gelir. 0 iade edilirse, eşit kabul edilir. Belgeleri her zaman okuyabilirsiniz: developer.mozilla .org /tr-tR /docs /Web /JavaScript /Referans /...
    2018-08-22 16: 54: 52Z
  4. @ BadFeelingAboutBu açıklama ve bağlantı için teşekkürler. İster inanın ister inanmayın, çeşitli kod snippet'lerini googledim1, 0, -1'u kullanarak bunu burada sormuştum. Sadece ihtiyacım olan bilgiyi bulamadım.
    2018-08-22 17: 07: 34Z

Prototip devralma kullanarak bu soruna basit ve hızlı bir çözüm:

 
Array.prototype.sortBy = function(p) {
  return this.slice(0).sort(function(a,b) {
    return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
  });
}

Örnek /Kullanım

 
objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];

objs.sortBy('age');
// Returns
// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]

objs.sortBy('name');
// Returns
// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]

Güncelleme: Artık orijinal diziyi değiştirmiyor.

    
42
2015-05-15 21: 45: 09Z
  1. Sadece başka bir dizi döndürmez. ancak aslında orijinal olanı sıralar !.
    2012-07-21 05: 43: 29Z
  2. Rakamlarla doğal bir sıralama kullandığınızdan emin olmak istiyorsanız (yani, 0,1,2,10,11 vb.) parseInt ile kullanın. Radix seti. developer.mozilla.org/en-US/docs/Web /JavaScript /Referans /… so: return (ayrıştırma (a [p], 10) > ayrıştırma (b [p], 10))? 1: (ayrıştırma (a [p], 10) ayrıştırma (b [p], 10))? -1: 0;
    2015-05-11 19: 14: 21Z
  3. @ codehuntr Düzeltdiğiniz için teşekkürler. ancak bu duyarlılığı yapmak için sıralama işlevi yapmak yerine, veri türlerini düzeltmek için ayrı bir işlev yaparsak daha iyi olur. Çünkü sıralama işlevi, hangi özelliğin hangi tür verileri içereceğini söyleyemez. :)
    2015-05-21 16: 55: 57Z
  4. Çok hoş. Artan /azalan efekti elde etmek için okları ters çevirin.
    2017-11-15 15: 08: 53Z
  5. asla, bir ana nesnenin prototipini değiştiren bir çözüm asla önermez
    2018-10-27 00: 17: 12Z

2018'den beri çok daha kısa ve zarif bir çözüm var. Sadece kullan. Array.prototype.sort () .

Örnek:

 
var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  return a.value - b.value;
});
    
29
2018-06-04 15: 24: 36Z
  1. Soruda dizgiler sayıların aksine karşılaştırma için kullanılmıştır. Cevabınız, numaralara göre sıralamak için harikadır, ancak dizeye göre karşılaştırma yapmak için iyi değildir.
    2018-06-18 10: 02: 18Z
  2. Nesnenin özniteliklerini karşılaştırmak için kullanılan a.value - b.value (bu durumda sayılar ) verilerin çeşitli zamanları için kabul edilebilir. Örneğin, regex, komşu dizeleri her çiftini karşılaştırmak için kullanılabilir.
    2019-03-26 09: 10: 16Z
  3. @ 0leg Burada, dizeleri bu şekilde karşılaştırmak için regex kullanmanın bir örneğini görmek istiyorum.
    2019-03-28 11: 30: 04Z

Özel bir karşılaştırma işlevi kullanmak yerine, özel toString() yöntemiyle (varsayılan karşılaştırma işlevi tarafından başlatılan) bir nesne türü de oluşturabilirsiniz:

 
function Person(firstName, lastName) {
    this.firtName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.lastName + ', ' + this.firstName;
}

var persons = [ new Person('Lazslo', 'Jamf'), ...]
persons.sort();
    
28
2009-07-15 07: 21: 48Z

Kullanabilirsiniz

En Kolay Yol: Lodash

( https://lodash.com/docs/4.17.10#orderBy )

Bu yöntem, yinelemelerin sıralama düzenlerini belirtmeye izin vermesi dışında, _.sortBy gibidir. Emir belirtilmemişse, tüm değerler artan düzende sıralanır. Aksi takdirde, azalan için "desc" sırasını veya karşılık gelen değerlerin artan sıralama düzenini "asc" olarak belirtin.

değişkenleri

collection (Array | Object): Yinelenecek koleksiyon. [iteratees = [_. identity]] (Array [] | Function [] | Object [] | string []): Sıralanacak yinelemeler. [orders] (string []): Yinelemelerin sıralama düzeni.

İade

(Dizi): Yeni sıralanan diziyi döndürür.


 
var _ = require('lodash');
var homes = [
    {"h_id":"3",
     "city":"Dallas",
     "state":"TX",
     "zip":"75201",
     "price":"162500"},
    {"h_id":"4",
     "city":"Bevery Hills",
     "state":"CA",
     "zip":"90210",
     "price":"319250"},
    {"h_id":"6",
     "city":"Dallas",
     "state":"TX",
     "zip":"75000",
     "price":"556699"},
    {"h_id":"5",
     "city":"New York",
     "state":"NY",
     "zip":"00010",
     "price":"962500"}
    ];

_.orderBy(homes, ['city', 'state', 'zip'], ['asc', 'desc', 'asc']);
    
23
2018-08-23 14: 39: 00Z

Lodash.js ( Underscore.js )

Her basit mantık parçası için bir çerçeve eklememek iyi değildir, ancak iyi test edilmiş bir yardımcı program çerçevesine güvenmek, gelişmeyi hızlandırmak ve yazılan hataları azaltmak utanç verici değildir.

Lodash çok temiz kod üretir ve daha az hatayla sonuçlanan daha işlevsel bir programlama stili sunar. Bir bakışta, kodun ne olacağı belli oluyor.

OP’nin sorunu şu şekilde çözülebilir:

 
const sortedObjs = _.sortBy(objs, 'last_nom');

Daha fazla bilgi? Örneğin. iç içe geçmiş nesneyi takip ettik:

 
const users = [
  { 'user': {'name':'fred', 'age': 48}},
  { 'user': {'name':'barney', 'age': 36 }},
  { 'user': {'name':'wilma'}},
  { 'user': {'name':'betty', 'age': 32}}
];

Artık, yolun belirtilmesi için _.property kestirme user.age’u kullanabiliriz. eşleştirilmesi gereken özellik. Kullanıcı nesnelerini iç içe yaş özelliğine göre sıralayacağız. Evet, iç içe özellik eşleştirmesine izin veriyor!

 
const sortedObjs = _.sortBy(users, ['user.age']);

Tersine çevrilsin mi? Sorun değil. _.reverse .

kullanın.  
const sortedObjs = _.reverse(_.sortBy(users, ['user.age']));

Her ikisini de Zincirleme 'yi kullanarak birleştirmek ister misiniz?

 
const sortedObjs = _.chain(users).sortBy('user.age').reverse().value();
    
22
2018-01-23 22: 42: 27Z

Burada çok iyi cevaplar var, ancak çok daha karmaşık bir sıralama elde etmek için çok basit bir şekilde genişletilebileceklerini belirtmek isterim. Yapmanız gereken tek şey, OR operatörünü, bunun gibi karşılaştırma fonksiyonlarını zincirlemek için kullanmaktır:

 
objs.sort((a,b)=> fn1(a,b) || fn2(a,b) || fn3(a,b) )

fn1, fn2, ... nerede dönen [-1,0,1] sıralama işlevleridir. Bu, "fn1 ile sıralama", "fn2 ile sıralama" ile sonuçlanır, ki bu da SQL'deki ORDER BY'a oldukça eşittir.

Bu çözüm,

Komut Dosyası:

 
/**
 * @description
 * Returns a function which will sort an
 * array of objects by the given key.
 *
 * @param  {String}  key
 * @param  {Boolean} reverse
 * @return {Function}
 */
const sortBy = (key, reverse) => {

  // Move smaller items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveSmaller = reverse ? 1 : -1;

  // Move larger items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveLarger = reverse ? -1 : 1;

  /**
   * @param  {*} a
   * @param  {*} b
   * @return {Number}
   */
  return (a, b) => {
    if (a[key] < b[key]) {
      return moveSmaller;
    }
    if (a[key] > b[key]) {
      return moveLarger;
    }
    return 0;
  };
};
    

19
2019-03-21 17: 18: 00Z
  1. bunu paylaştığınız için teşekkür ederiz, 1, 0, -1 rakamlarının neden sıralama düzeni için kullanıldığını anlamaya çalışıyorum. Yukarıdaki açıklamanla bile, ki çok iyi görünüyor-- Hala değilimTam olarak anlayamadım. Her zaman -1'u dizi uzunluğu özelliğini kullanırken düşünüyorum, yani .: arr.length = -1, öğenin bulunamadığı anlamına gelir. Muhtemelen burada işleri karıştırıyorum, ama neden 1, 0, -1 rakamlarının siparişi belirlemek için kullanıldığını anlamama yardım eder misin? Teşekkürler.
    2018-08-22 06: 23: 56Z
  2. Bu tamamen doğru değil ancak böyle düşünmek yardımcı olabilir: array.sort'a iletilen işlev bir kez çağrılır dizideki her öğe, "a" adlı argüman olarak. Her işlev çağrısının dönüş değeri, "a" maddesinin indeksinin (geçerli konum numarası) bir sonraki "b" maddesine kıyasla nasıl değiştirilmesi gerektiğidir. Dizin, dizinin sırasını belirler (0, 1, 2 vb.) Eğer "a", 5. dizinde ise ve -1 ve sonra 5 + -1 == 4 döndürürseniz (onu daha ileriye götür) 5 + 0 == 5 (olduğu yerde saklayın) vb. Diziyi, sonuna kadar 2 komşuyu karşılaştırarak sonuna kadar sıralar ve diziyi sıralar.
    2018-08-23 09: 09: 35Z
  3. bunu daha fazla açıklamaya zaman ayırdığınız için teşekkür ederiz. Bu nedenle açıklamanızı ve MDN Array.prototype .sort , size bu konuda ne düşündüğümü söyleyeceğim: a ve b ile karşılaştırıldığında, a b'dan büyükse, a'un dizinine 1 ekleyin ve b'un daha düşük olması durumunda a'un arkasına yerleştirin b’dan daha fazla, a’dan 1’i çıkarın ve b’un önüne yerleştirin. a ve b aynıysa, 0'dan a'a ekleyin ve olduğu yerde bırakın.
    2018-08-23 16: 28: 58Z
  4. Bu bana iyi geliyor @ Chris22, teşekkürler.
    2018-08-24 14: 13: 10Z

Benim için çalışan bir kodum var:

 
arr.sort((a, b) => a.name > b.name)

GÜNCELLEME: Her zaman çalışmıyor, bu yüzden doğru değil :(

    
17
2017-12-07 22: 51: 14Z
  1. Çalışıyor, ancak sonuç bir nedenden dolayı kararsız.
    2018-02-03 19: 55: 05Z
  2. '>' yerine '-' kullanın. Bu işe yarayacak.
    2018-02-15 16: 43: 41Z
  3. @ AO17 hayır olmaz. Dizeleri çıkaramazsınız.
    2018-07-18 09: 23: 04Z
  4. Bunu yapmalı: arr.sort((a, b) => a.name < b.name ? -1 : (a.name > b.name ? 1 : 0))
    2018-08-29 15: 33: 21Z
  5. @ Jean-FrançoisBeauchamp, çözümünüz gayet iyi ve çok daha iyi çalışıyor.
    2019-01-22 13: 49: 26Z

Bu özel yaklaşımı önermedim, bu yüzden işte string ve number için de işe yarayan bir karşılaştırma yöntemi kullanıyorum:

 
const objs = [ 
  { first_nom: 'Lazslo', last_nom: 'Jamf'     },
  { first_nom: 'Pig',    last_nom: 'Bodine'   },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

const sortBy = fn => (a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}
const getLastName = o => o.last_nom
const sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))

İşte sortBy()'un açıklaması:

sortBy(), karşılaştırma olarak bir nesneden hangi değeri kullanacağını seçen ve doğrudan fn'a aktarılabilen bir işlevi döndüren bir Array.prototype.sort()'u kabul eder. Bu örnekte, karşılaştırma değeri olarak o.last_nom kullanıyoruz, bu yüzden ne zaman Array.prototype.sort() ile

gibi iki nesne aldığımızda  
{ first_nom: 'Lazslo', last_nom: 'Jamf' }

ve

 
{ first_nom: 'Pig', last_nom: 'Bodine' }

kullanıyoruz

 
(a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}

bunları karşılaştırmak için.

fn = o => o.last_nom’u hatırlayarak, karşılaştırma işlevini eşdeğerine genişletebiliriz

 
(a, b) => {
  const fa = a.last_nom
  const fb = b.last_nom
  return -(fa < fb) || +(fa > fb)
}

Mantıksal OR || operatörü, burada çok kullanışlı olan kısa devre işlevselliğine sahiptir. Nasıl çalıştığından dolayı yukarıdaki işlevin gövdesi

anlamına gelir.  
if (fa < fb) return -1
return +(fa > fb)

Öyleyse, fa < fb, -1 döndürürsek, aksi takdirdefa > fb ise +1 döndürürsek, fa == fb, fa < fb ve fa > fb false olursa, +0 döndürür.

Eklenen bir bonus olarak, ECMAScript 5'te ok işlevsiz eşdeğerdir, ki maalesef daha ayrıntılıdır:

 
var objs = [ 
  { first_nom: 'Lazslo', last_nom: 'Jamf'     },
  { first_nom: 'Pig',    last_nom: 'Bodine'   },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortBy = function (fn) {
  return function (a, b) {
    var fa = fn(a)
    var fb = fn(b)
    return -(fa < fb) || +(fa > fb)
  }
}

var getLastName = function (o) { return o.last_nom }
var sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))
    
16
2019-04-30 07: 35: 38Z

Bu sorunun çok eski olduğunu biliyorum, ancak benimkine benzer bir uygulama görmedim.
Bu sürüm Schwartzian dönüşüm deyimini temel alır.

 
function sortByAttribute(array, ...attrs) {
  // generate an array of predicate-objects contains
  // property getter, and descending indicator
  let predicates = attrs.map(pred => {
    let descending = pred.charAt(0) === '-' ? -1 : 1;
    pred = pred.replace(/^-/, '');
    return {
      getter: o => o[pred],
      descend: descending
    };
  });
  // schwartzian transform idiom implementation. aka: "decorate-sort-undecorate"
  return array.map(item => {
    return {
      src: item,
      compareValues: predicates.map(predicate => predicate.getter(item))
    };
  })
  .sort((o1, o2) => {
    let i = -1, result = 0;
    while (++i < predicates.length) {
      if (o1.compareValues[i] < o2.compareValues[i]) result = -1;
      if (o1.compareValues[i] > o2.compareValues[i]) result = 1;
      if (result *= predicates[i].descend) break;
    }
    return result;
  })
  .map(item => item.src);
}

İşte nasıl kullanılacağına bir örnek:

 
let games = [
  { name: 'Pako',              rating: 4.21 },
  { name: 'Hill Climb Racing', rating: 3.88 },
  { name: 'Angry Birds Space', rating: 3.88 },
  { name: 'Badland',           rating: 4.33 }
];

// sort by one attribute
console.log(sortByAttribute(games, 'name'));
// sort by mupltiple attributes
console.log(sortByAttribute(games, '-rating', 'name'));
    
15
2016-11-06 13: 26: 18Z

Sıralama (daha fazla) Nesnelerin Karmaşık Dizileri

Muhtemelen bu dizi gibi daha karmaşık veri yapılarıyla karşılaştığınız için çözümü genişletirim.

TL; DR

  

@ ege-Özcan 'a dayanarak daha takılabilir sürümdür çok güzel cevap .

Sorun

Aşağıdakiyle karşılaştım ve değiştiremedim. Ayrıca nesneyi geçici olarak düzleştirmek istemedim. Ben de özellikle performans nedeniyle ve kendimi uygulama eğlencesi için alt çizgi /lodash kullanmak istemedim.

 
var People = [
   {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},
   {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},
   {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}
];

Hedef

Amaç, öncelikle People.Name.name'a, ikincil olarak People.Name.surname'a göre sıralamaktır

Engeller

Şimdi, temel çözümde, dinamik olarak sıralamak için özellikleri hesaplamak için parantez gösterimi kullanılır. Yine de, burada, bizzat People['Name.name']'un çalışacağını bekleyeceğinizden, braket notasyonunu dinamik olarak da oluşturmak zorunda kalacağız.

Diğer taraftan, yalnızca People['Name']['name']'u yapmak statiktir ve yalnızca n -düzeyine inmenize izin verir.

Çözüm

Buradaki ana ekleme, nesne ağacında dolaşmak ve son yaprağın değerini, belirtmeniz gereken herhangi bir aracı yaprağın değerini belirlemek olacaktır.

 
var People = [
   {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},
   {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},
   {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}
];

People.sort(dynamicMultiSort(['Name','name'], ['Name', '-surname']));
// Results in...
// [ { Name: { name: 'AAA', surname: 'ZZZ' }, Middlename: 'Abrams' },
//   { Name: { name: 'Name', surname: 'Surname' }, Middlename: 'JJ' },
//   { Name: { name: 'Name', surname: 'AAA' }, Middlename: 'Wars' } ]

// same logic as above, but strong deviation for dynamic properties 
function dynamicSort(properties) {
  var sortOrder = 1;
  // determine sort order by checking sign of last element of array
  if(properties[properties.length - 1][0] === "-") {
    sortOrder = -1;
    // Chop off sign
    properties[properties.length - 1] = properties[properties.length - 1].substr(1);
  }
  return function (a,b) {
    propertyOfA = recurseObjProp(a, properties)
    propertyOfB = recurseObjProp(b, properties)
    var result = (propertyOfA < propertyOfB) ? -1 : (propertyOfA > propertyOfB) ? 1 : 0;
    return result * sortOrder;
  };
}

/**
 * Takes an object and recurses down the tree to a target leaf and returns it value
 * @param  {Object} root - Object to be traversed.
 * @param  {Array} leafs - Array of downwards traversal. To access the value: {parent:{ child: 'value'}} -> ['parent','child']
 * @param  {Number} index - Must not be set, since it is implicit.
 * @return {String|Number}       The property, which is to be compared by sort.
 */
function recurseObjProp(root, leafs, index) {
  index ? index : index = 0
  var upper = root
  // walk down one level
  lower = upper[leafs[index]]
  // Check if last leaf has been hit by having gone one step too far.
  // If so, return result from last step.
  if (!lower) {
    return upper
  }
  // Else: recurse!
  index++
  // HINT: Bug was here, for not explicitly returning function
  // https://stackoverflow.com/a/17528613/3580261
  return recurseObjProp(lower, leafs, index)
}

/**
 * Multi-sort your array by a set of properties
 * @param {...Array} Arrays to access values in the form of: {parent:{ child: 'value'}} -> ['parent','child']
 * @return {Number} Number - number for sort algorithm
 */
function dynamicMultiSort() {
  var args = Array.prototype.slice.call(arguments); // slight deviation to base

  return function (a, b) {
    var i = 0, result = 0, numberOfProperties = args.length;
    // REVIEW: slightly verbose; maybe no way around because of `.sort`-'s nature
    // Consider: `.forEach()`
    while(result === 0 && i < numberOfProperties) {
      result = dynamicSort(args[i])(a, b);
      i++;
    }
    return result;
  }
}

Örnek

Çalışma örneği JSBin'de

    
14
2017-05-23 12: 18: 33Z
  1. Neden? Bu, asıl sorunun cevabı değildir ve "amaç" basitçe People.sort ((a, b) = > {return a.Name.name.localeCompare (b.Name.name) || a ile çözülebilir. Name.surname.localeCompare (b.Name.surname)})
    2016-05-03 16: 02: 05Z

Bir seçenek daha:

 
var someArray = [...];

function generateSortFn(prop, reverse) {
    return function (a, b) {
        if (a[prop] < b[prop]) return reverse ? 1 : -1;
        if (a[prop] > b[prop]) return reverse ? -1 : 1;
        return 0;
    };
}

someArray.sort(generateSortFn('name', true));

, varsayılan olarak artan sıralar.

    
11
2016-06-26 09: 10: 05Z
  1. Bu çözüm temiz kod için yapar. Harika çalışıyor.
    2016-11-30 18: 14: 06Z
  2. Gerekirse, birden çok alana göre sıralama yapmak için biraz değiştirilmiş sürüm burada: stackoverflow.com/questions/6913512/…
    2016-12-01 12: 37: 39Z

Basit bir yol:

 
objs.sort(function(a,b) {
  return b.last_nom.toLowerCase() < a.last_nom.toLowerCase();
});

Bkz. '.toLowerCase()', hataları önlemek için gerekli dizeleri karşılaştırırken.

    
10
2016-01-15 13: 32: 57Z
  1. ok işlevleri , kodu biraz daha şık hale getirmek için: objs.sort( (a,b) => b.last_nom.toLowerCase() < a.last_nom.toLowerCase() );
    2017-05-24 15: 04: 33Z
  2. buradan .
    2018-07-18 09: 24: 37Z
  3. Ok işlevleri ES5'e uygun değil. Tonlarca motor hala ES5 ile sınırlı. Benim durumumda, ES5 motorunda olduğum için (şirketim tarafından zorlanan) yukarıda verilen cevabı önemli ölçüde daha iyi buluyorum
    2018-07-21 08: 50: 37Z

    Ege Özcan kodu için ek indirme paragrafları

     
    function dynamicSort(property, desc) {
        if (desc) {
            return function (a, b) {
                return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0;
            }   
        }
        return function (a, b) {
            return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        }
    }
    
        
    9
    2012-09-16 20: 22: 18Z

    Ege'nin dinamik çözümünü Vinay'in fikriyle birleştirerek güzel ve sağlam bir çözüm elde edersiniz:

     
    Array.prototype.sortBy = function() {
        function _sortByAttr(attr) {
            var sortOrder = 1;
            if (attr[0] == "-") {
                sortOrder = -1;
                attr = attr.substr(1);
            }
            return function(a, b) {
                var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;
                return result * sortOrder;
            }
        }
        function _getSortFunc() {
            if (arguments.length == 0) {
                throw "Zero length arguments not allowed for Array.sortBy()";
            }
            var args = arguments;
            return function(a, b) {
                for (var result = 0, i = 0; result == 0 && i < args.length; i++) {
                    result = _sortByAttr(args[i])(a, b);
                }
                return result;
            }
        }
        return this.sort(_getSortFunc.apply(null, arguments));
    }
    

    Kullanım:

     
    // Utility for printing objects
    Array.prototype.print = function(title) {
        console.log("************************************************************************");
        console.log("**** "+title);
        console.log("************************************************************************");
        for (var i = 0; i < this.length; i++) {
            console.log("Name: "+this[i].FirstName, this[i].LastName, "Age: "+this[i].Age);
        }
    }
    
    // Setup sample data
    var arrObj = [
        {FirstName: "Zach", LastName: "Emergency", Age: 35},
        {FirstName: "Nancy", LastName: "Nurse", Age: 27},
        {FirstName: "Ethel", LastName: "Emergency", Age: 42},
        {FirstName: "Nina", LastName: "Nurse", Age: 48},
        {FirstName: "Anthony", LastName: "Emergency", Age: 44},
        {FirstName: "Nina", LastName: "Nurse", Age: 32},
        {FirstName: "Ed", LastName: "Emergency", Age: 28},
        {FirstName: "Peter", LastName: "Physician", Age: 58},
        {FirstName: "Al", LastName: "Emergency", Age: 51},
        {FirstName: "Ruth", LastName: "Registration", Age: 62},
        {FirstName: "Ed", LastName: "Emergency", Age: 38},
        {FirstName: "Tammy", LastName: "Triage", Age: 29},
        {FirstName: "Alan", LastName: "Emergency", Age: 60},
        {FirstName: "Nina", LastName: "Nurse", Age: 54}
    ];
    
    //Unit Tests
    arrObj.sortBy("LastName").print("LastName Ascending");
    arrObj.sortBy("-LastName").print("LastName Descending");
    arrObj.sortBy("LastName", "FirstName", "-Age").print("LastName Ascending, FirstName Ascending, Age Descending");
    arrObj.sortBy("-FirstName", "Age").print("FirstName Descending, Age Ascending");
    arrObj.sortBy("-Age").print("Age Descending");
    
        
    9
    2013-04-23 16: 07: 34Z
    1. Fikir için teşekkürler! Bu arada, lütfen insanları Dizi Prototipini değiştirmeye teşvik etmeyin (örneğimin sonundaki uyarıya bakın).
      2013-05-10 14: 51: 08Z

    Bir nesnenin dizisini bir özelliğe göre sıralayan basit bir işlev

     
    function sortArray(array, property, direction) {
        direction = direction || 1;
        array.sort(function compare(a, b) {
            let comparison = 0;
            if (a[property] > b[property]) {
                comparison = 1 * direction;
            } else if (a[property] < b[property]) {
                comparison = -1 * direction;
            }
            return comparison;
        });
        return array; // Chainable
    }
    

    Kullanım:

     
    var objs = [ 
        { first_nom: 'Lazslo', last_nom: 'Jamf'     },
        { first_nom: 'Pig',    last_nom: 'Bodine'   },
        { first_nom: 'Pirate', last_nom: 'Prentice' }
    ];
    
    sortArray(objs, "last_nom"); // Asc
    sortArray(objs, "last_nom", -1); // Desc
    
        
    9
    2018-05-28 19: 54: 49Z

    Örneğinize göre, bir taneden çok iki alana (soyadı, adı) sıralamanız gerekir. Bu sıralamayı bir satırda yapmak için Alasql kütüphanesini kullanabilirsiniz:

     
    var res = alasql('SELECT * FROM ? ORDER BY last_nom, first_nom',[objs]);
    

    Bu örneği deneyin jsFiddle'da .

        
    8
    2014-12-18 11: 09: 04Z
     
    objs.sort(function(a,b){return b.last_nom>a.last_nom})
    
        
    8
    2016-03-08 09: 51: 36Z
    1. Aslında işe yaramadı, kabul edilen cevabı kullanmak zorunda kaldı. Doğru sıralanmadı.
      2017-02-21 11: 15: 32Z

    Karışıklığı önlemek için bunları küçük harfe dönüştürmeniz gerekebilir.

     
    objs.sort(function (a,b) {
    
    var nameA=a.last_nom.toLowerCase(), nameB=b.last_nom.toLowerCase()
    
    if (nameA < nameB)
      return -1;
    if (nameA > nameB)
      return 1;
    return 0;  //no sorting
    
    })
    
        
    7
    2013-08-14 10: 40: 10Z
    function compare(propName) {
        return function(a,b) {
            if (a[propName] < b[propName])
                return -1;
            if (a[propName] > b[propName])
                return 1;
            return 0;
        };
    }
    
    objs.sort(compare("last_nom"));
    
        
    7
    2015-10-29 13: 09: 48Z
    1. Lütfen kodunuzun ne yaptığı ve sorunu neden çözeceği hakkında daha fazla açıklama eklemek için yayınınızı düzenlemeyi düşünün. Çoğunlukla sadece kod içeren bir cevap (çalışıyor olsa bile) genellikle OP'ye problemlerini anlamada yardımcı olmaz.
      2015-10-29 18: 16: 07Z

    Orijinal örnek verilen:

     
    var objs = [ 
        { first_nom: 'Lazslo', last_nom: 'Jamf'     },
        { first_nom: 'Pig',    last_nom: 'Bodine'   },
        { first_nom: 'Pirate', last_nom: 'Prentice' }
    ];
    

    Birden çok alana göre sıralayın:

     
    objs.sort(function(left, right) {
        var last_nom_order = left.last_nom.localeCompare(right.last_nom);
        var first_nom_order = left.first_nom.localeCompare(right.first_nom);
        return last_nom_order || first_nom_order;
    });
    

    Notlar

    •  a.localeCompare(b), evrensel olarak desteklenir ve sırasıyla a<b, a==b, a>b iken -1,0,1 döndürür.
    •  Son satırdaki ||, last_nom’dan first_nom’a öncelik veriyor.
    • Çıkarma sayısal alanlarda çalışır: var age_order = left.age - right.age;
    • Sıralamayı tersine çevir, return -last_nom_order || -first_nom_order || -age_order;
    7
    2018-02-24 00: 54: 56Z

    Bu basit bir sorundur, insanların neden bu kadar karmaşık bir çözüme sahip olduklarını bilmiyorum.
    Basit bir sıralama işlevi ( hızlı sıralama algoritmasına bağlı olarak):

     
    function sortObjectsArray(objectsArray, sortKey)
            {
                // Quick Sort:
                var retVal;
    
                if (1 < objectsArray.length)
                {
                    var pivotIndex = Math.floor((objectsArray.length - 1) / 2);  // middle index
                    var pivotItem = objectsArray[pivotIndex];                    // value in the middle index
                    var less = [], more = [];
    
                    objectsArray.splice(pivotIndex, 1);                          // remove the item in the pivot position
                    objectsArray.forEach(function(value, index, array)
                    {
                        value[sortKey] <= pivotItem[sortKey] ?                   // compare the 'sortKey' proiperty
                            less.push(value) :
                            more.push(value) ;
                    });
    
                    retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));
                }
                else
                {
                    retVal = objectsArray;
                }
    
                return retVal;
            }
    

    Örnek kullanın:

     
    var myArr = 
            [
                { val: 'x', idx: 3 },
                { val: 'y', idx: 2 },
                { val: 'z', idx: 5 },
            ];
    myArr = sortObjectsArray(myArr, 'idx');
    
        
    6
    2015-11-19 14: 27: 57Z
    1. js'de hızlı sıralama nasıl basit bir çözümdür? Basit algoritma ama basit bir çözüm değil.
      2015-11-23 22: 46: 09Z
    2. Herhangi bir dış kitaplık kullanmadığından ve nesnenin prototipini değiştirmediğinden basittir. Benim düşünceme göre, kodun uzunluğu, kodun karmaşıklığı üzerinde doğrudan bir etkiye sahip değildir
      2015-11-24 12: 02: 20Z
    3. Pekala, farklı kelimelerle deneyeyim: Tekerleği yeniden icat etmek basit bir çözümdür?
      2015-12-09 17: 36: 20Z

    Ramda'yı Kullanma

    npm ramda yükleme

     
    import R from 'ramda'
    var objs = [ 
        { first_nom: 'Lazslo', last_nom: 'Jamf'     },
        { first_nom: 'Pig',    last_nom: 'Bodine'   },
        { first_nom: 'Pirate', last_nom: 'Prentice' }
    ];
    var ascendingSortedObjs = R.sortBy(R.prop('last_nom'), objs)
    var descendingSortedObjs = R.reverse(ascendingSortedObjs)
    
        
    6
    2017-07-05 07: 43: 55Z

    Sadece nesnelerin derinliklerine dalmak için Ege Özcan 'ın dinamik türünü geliştirdim. Veriler şöyle görünüyorsa:

     
    obj = [
        {
            a: { a: 1, b: 2, c: 3 },
            b: { a: 4, b: 5, c: 6 }
        },
        { 
            a: { a: 3, b: 2, c: 1 },
            b: { a: 6, b: 5, c: 4 }
    }];
    

    ve a.a özelliğine göre sıralamak istiyorsanız, geliştirmemin çok yardımcı olduğunu düşünüyorum. Bunun gibi nesnelere yeni işlevler ekliyorum:

     
    Object.defineProperty(Object.prototype, 'deepVal', {
        enumerable: false,
        writable: true,
        value: function (propertyChain) {
            var levels = propertyChain.split('.');
            parent = this;
            for (var i = 0; i < levels.length; i++) {
                if (!parent[levels[i]])
                    return undefined;
                parent = parent[levels[i]];
            }
            return parent;
        }
    });
    

    ve _dynamicSort 'un return işlevini değiştirdi:

     
    return function (a,b) {
            var result = ((a.deepVal(property) > b.deepVal(property)) - (a.deepVal(property) < b.deepVal(property)));
            return result * sortOrder;
        }
    

    Artık a.a. ile şu şekilde sıralayabilirsiniz:

     
    obj.sortBy('a.a');
    

    JSFiddle

    'daki Commplete betiğini görün     
    5
    2017-05-23 12: 03: 09Z
kaynak yerleştirildi İşte