Underscore.js kullanarak nasıl bir asc ve desc sıralaması yapabilirim?


166

Şu anda benim json sıralama sıralamak için underscorejs kullanıyorum. Şimdi underscore.js kullanarak bir ascendingve descendingsıralama yapmak istedim . Belgelerde bununla ilgili hiçbir şey göremiyorum. Bunu nasıl başarabilirim?


1
Lütfen ne sıraladığınıza ve nasıl sıraladığınıza bir örnek ekleyin.
Jon

Ne sıralıyorsun? Sayılar? Teller? Tarih? Başka bir şey?
mu çok kısa

@muistooshort Bir dizi nesneyi sıralıyorum. Yani sortBy yöntemi, artan sıralama için kriterlerime mükemmel şekilde uyuyor, ancak tam tersi değil.
Rahul

Bir sayıya göre sıralıyorsanız, sortByişleviniz olabilir, return -nancak bu dizeler için çalışmaz; dolayısıyla ne tür şeyleri sıraladığınız sorusu.
mu çok kısa

2
Lodash ile, Array'ın prototipini kullanmak istemiyorsanız _.sortBy([1,4,3,2]).reverse()veya _.chain([1,4,3,2]).sortBy().reverse().value()istemiyorsanız steno kullanabilirsiniz reverse().
GFoley83

Yanıtlar:


363

Kullanabilirsiniz, .sortByher zaman artan bir liste döndürür :

_.sortBy([2, 3, 1], function(num) {
    return num;
}); // [1, 2, 3]

Ama kullanabilirsiniz .reverse alabileceğin yöntemi inen :

var array = _.sortBy([2, 3, 1], function(num) {
    return num;
});

console.log(array); // [1, 2, 3]
console.log(array.reverse()); // [3, 2, 1]

Veya sayılarla uğraşırken listeye inmek için geri dönüşe negatif bir işaret ekleyin:

_.sortBy([-3, -2, 2, 3, 1, 0, -1], function(num) {
    return -num;
}); // [3, 2, 1, 0, -1, -2, -3]

Kaputun altında .sortByyerleşik kullanır .sort([handler]):

// Default is ascending:
[2, 3, 1].sort(); // [1, 2, 3]

// But can be descending if you provide a sort handler:
[2, 3, 1].sort(function(a, b) {
    // a = current item in array
    // b = next item in array
    return b - a;
});

9
Son çözüm yani döndürülen num'a negatif işaret eklemek mükemmeldir.
vinesh

Neden böyle bir kabarcık olduğunu düşünüyorsun? Kaputun altında, algoritması tarayıcı satıcılarına bağlı olan .sortBy()yerleşik çağrılar var Array.sort(), ancak kabarcık sıralamasının seçimleri olma olasılığı düşük.
Rene Saarsoo

Bu zaman karmaşıklığını artırmıyor mu? Listenin iki kez sıralanmasına neden olur.
user1477388

@ user1477388 Ne demek istediğinizi iki kez sıraladığınızdan emin değil misiniz?
andlrc

@andlrc Yani, aradığınızda _.sortBy(arr, function), her öğenin üzerinde döngüler olduğunu ve sıralı diziyi döndürmek için bazı mantık yürüttüğünü varsayıyorum. Sonra, çağırdığınızda Array.prototype.reverse(), muhtemelen her öğenin üzerine tekrar döngüler ve ters dizi döndürmek için bazı mantık yürütür. Bu nedenle, dizi iki kez döngü.
user1477388

57

Alt çizgi kullanılarak azalan sıralama, dönüş değeri -1 ile çarpılarak yapılabilir.

//Ascending Order:
_.sortBy([2, 3, 1], function(num){
    return num;
}); // [1, 2, 3]


//Descending Order:
_.sortBy([2, 3, 1], function(num){
    return num * -1;
}); // [3, 2, 1]

Sayılarla değil dizelerle sıralıyorsanız, unicode değerini almak için charCodeAt () yöntemini kullanabilirsiniz.

//Descending Order Strings:
_.sortBy(['a', 'b', 'c'], function(s){ 
    return s.charCodeAt() * -1;
});

3
Alfabetik sıralamaya çalışıyorum - -1 ile çarpmak geçerli bir işlem değil. :)
rythos42

Kullanım durumunda bir değer ama soruda belirtilmemiş. Ancak, bir dizeyi -1 ile çarpmak geçerli bir işlemdir. Geçerli bir sonuç olan NaN değerini döndürür.
jEremyB

1
diziyi de yeniden atamayı unutmayın! SOME_ARR = _.sortBy (SOME_ARR, işlev (num) {SOME_FUNC ...});
aqm

4
charCodeAt "bir dizede belirtilen dizindeki karakterin Unicode'unu döndürür", böylece bir dizedeki karakterlere göre sıralamak için kullanılabilir, ancak gösterildiği gibi "dizeye göre sırala" değildir , dizedeki bir karaktere göre sıralar
Anthony

2
Bu sadece ilk karaktere göre sıralanır ve büyük / küçük harfe duyarlıdır.
aidan

50

Dizi prototipin ters yöntem değiştirir Bunu yapmanın anlamı dizisi ve döner buna bir referans:

var sortedAsc = _.sortBy(collection, 'propertyName');
var sortedDesc = _.sortBy(collection, 'propertyName').reverse();

Ayrıca, alt çizgi belgelerinde şunlar bulunur:

Ayrıca, Array prototipinin yöntemleri zincirlenmiş Alt Çizgi nesnesi aracılığıyla proxy'ye bağlanır, böylece zincirinize a reverseveya a pushkaydırabilir ve diziyi değiştirmeye devam edebilirsiniz.

yani .reverse()zincirleme yaparken de kullanabilirsiniz :

var sortedDescAndFiltered = _.chain(collection)
    .sortBy('propertyName')
    .reverse()
    .filter(_.property('isGood'))
    .value();

Bu, en basit kullanım durumlarında, ters / azalan sıralama için en basit yöntemdir.
Dan Atkinson

2
Büyük / küçük harfe duyarlı olmayan bir alfabetik sıralama yapmak için:_.sortBy(collection, item => item. propertyName.toLowerCase());
XåpplI'-I0llwlg'I -

dizide negatif sayılar varsa bu çalışmaz.
Shruti Kapoor

@ShrutiKapoor Evet öyle. Neden olmasın?
Emil Lundberg

5
Performans açısından, önce filtreyi uygulamak ve sonra değerleri (kalan) sıralamak tercih edilir.
Saran

12

Alt çizgi kitaplığına benzer şekilde, "sırayla" adı verilen ve sıralamanın hangi sırada sıralanacağını belirlemek için parametreyi alan "orderBy" yöntemine sahip başka bir kitaplık vardır. Gibi kullanabilirsiniz

_.orderBy('collection', 'propertyName', 'desc')

Herhangi bir nedenle, web sitesi belgelerinde belgelenmemiştir.


Ne karıştı düşünüyorum alt çizgi ile lodash . Sadece ikincisi belirtilen orderBy işlevine sahiptir .
Thomas Marti

Evet, benim hatam. Cevabı güncelleyecek.
Düzelttiğiniz

orderBy, süper yararlı! Aradığım istikrarlı sıralama özelliğini koruduğundan, ters kullanmaktan çok daha iyi.
Flimm

Bazı nedenlerden dolayı benim için çalışmıyor: onun lodash (
aleXela

0

Alt Çizgi Karışımları

@ Emil_lundberg yanıtını genişleterek, bir uygulamada bir yerde tekrarlayabileceğiniz bir tür sıralama ise sıralamak için özel bir işlev yapmak için Underscore kullanıyorsanız, bir "mixin" de yazabilirsiniz.

Örneğin, "ASC" veya "DESC" sıralama düzenine sahip bir denetleyiciniz veya sıralama sonuçlarını görüntüleyebilirsiniz ve bu sıralama arasında geçiş yapmak istiyorsanız, bunun gibi bir şey yapabilirsiniz:

Mixin.js

_.mixin({
    sortByOrder: function(stooges, prop, order) {
      if (String(order) === "desc") {
          return _.sortBy(stooges, prop).reverse();
      } else if (String(order) === "asc") {
          return _.sortBy(stooges, prop);
      } else {
          return stooges;
      }
    }
})

Kullanım Örneği

var sort_order = "asc";
var stooges = [
  {name: 'moe', age: 40}, 
  {name: 'larry', age: 50}, 
  {name: 'curly', age: 60},
  {name: 'July', age: 35},
  {name: 'mel', age: 38}
 ];

_.mixin({
    sortByOrder: function(stooges, prop, order) {
    if (String(order) === "desc") {
        return _.sortBy(stooges, prop).reverse();
    } else if (String(order) === "asc") {
        return _.sortBy(stooges, prop);
    } else {
        return stooges;
    }
  }
})


// find elements
var banner = $("#banner-message");
var sort_name_btn = $("button.sort-name");
var sort_age_btn = $("button.sort-age");

function showSortedResults(results, sort_order, prop) {
    banner.empty();
    banner.append("<p>Sorting: " + prop + ', ' + sort_order + "</p><hr>")
  _.each(results, function(r) {
    banner.append('<li>' + r.name + ' is '+ r.age + ' years old.</li>');
  }) 
}

// handle click and add class
sort_name_btn.on("click", function() {
  sort_order = (sort_order === "asc") ? "desc" : "asc"; 
    var sortedResults = _.sortByOrder(stooges, 'name', sort_order);
  showSortedResults(sortedResults, sort_order, 'name');
})

sort_age_btn.on('click', function() {
    sort_order = (sort_order === "asc") ? "desc" : "asc"; 
    var sortedResults = _.sortByOrder(stooges, 'age', sort_order);
  showSortedResults(sortedResults, sort_order, 'age');
})

İşte bunu gösteren bir JSFiddle: SortBy Mixin için JSFiddle

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.