ฉันจะเรียงลำดับ asc และ desc โดยใช้ underscore.js ได้อย่างไร


166

ขณะนี้ฉันใช้เครื่องหมายขีดล่างเพื่อจัดเรียง json ของฉัน ตอนนี้ฉันได้ขอให้ทำascendingและdescendingเรียงลำดับโดยใช้ underscore.js ฉันไม่เห็นอะไรเกี่ยวกับสิ่งเดียวกันในเอกสารประกอบ ฉันจะบรรลุสิ่งนี้ได้อย่างไร


1
โปรดเพิ่มตัวอย่างสิ่งที่คุณกำลังเรียงลำดับและวิธีการ
Jon

คุณกำลังเรียงลำดับอะไร เบอร์? สตริง? วันที่? อื่น ๆ อีก?
mu สั้นเกินไป

@muistooshort ฉันกำลังเรียงลำดับอาร์เรย์ของวัตถุ ดังนั้นวิธี sortBy เหมาะสมกับเกณฑ์ของฉันอย่างสมบูรณ์แบบสำหรับเรียงลำดับจากน้อยไปมาก แต่ไม่ใช่วิธีอื่น ๆ
ราหุล

หากคุณเรียงลำดับตามตัวเลขsortByฟังก์ชันของคุณอาจเป็นไปได้return -nแต่นั่นจะใช้ไม่ได้กับสตริง ดังนั้นคำถามเกี่ยวกับสิ่งที่คุณเรียงลำดับ
mu สั้นเกินไป

2
ด้วย Lodash คุณสามารถใช้ชวเลขเหมือน_.sortBy([1,4,3,2]).reverse()หรือ_.chain([1,4,3,2]).sortBy().reverse().value()ถ้าคุณไม่ต้องการใช้reverse()ต้นแบบของ Array
GFoley83

คำตอบ:


363

คุณสามารถใช้.sortByมันจะส่งคืนรายการจากน้อยไปมาก :

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

แต่คุณสามารถใช้วิธี. reverseเพื่อให้มันลดหลั่นลงมา :

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

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

หรือเมื่อจัดการกับตัวเลขให้เพิ่มเครื่องหมายลบเพื่อกลับไปสู่รายการ:

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

ภายใต้ประทุน.sortByใช้ตัวใน.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
ทางออกสุดท้ายคือการเพิ่มเครื่องหมายลบไปยัง NUM ที่ส่งคืนนั้นสมบูรณ์แบบ
vinesh

ทำไมคุณคิดว่ามันเป็นฟองเรียง? ภายใต้ประทุน.sortBy()เรียกตัวในArray.sort()ตัวอัลกอริทึมซึ่งขึ้นอยู่กับผู้ขายเบราว์เซอร์ แต่การเรียงลำดับฟองค่อนข้างน่าจะเป็นทางเลือกของพวกเขา
Rene Saarsoo

สิ่งนี้ไม่ได้เพิ่มความซับซ้อนของเวลาหรือไม่ ทำให้รายการถูกเรียงลำดับสองครั้ง
user1477388

@ user1477388 ฉันไม่แน่ใจว่าคุณหมายถึงอะไรเกี่ยวกับการจัดเรียงสองครั้ง?
andlrc

@ andlrc ดังนั้นเมื่อคุณโทร_.sortBy(arr, function)ฉันคิดว่ามันวนซ้ำแต่ละรายการและดำเนินการตรรกะบางอย่างเพื่อกลับอาร์เรย์เรียง จากนั้นเมื่อคุณเรียกArray.prototype.reverse()มันอาจจะวนซ้ำแต่ละรายการอีกครั้งและดำเนินการตรรกะบางอย่างเพื่อส่งกลับอาร์เรย์ที่กลับรายการ ดังนั้นคุณจึงวนลูปอาร์เรย์สองครั้ง
user1477388

57

ลำดับจากมากไปน้อยโดยใช้ขีดล่างสามารถทำได้โดยการคูณค่าส่งคืนด้วย -1

//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]

หากคุณเรียงลำดับตามสตริงที่ไม่ใช่ตัวเลขคุณสามารถใช้เมธอด charCodeAt () เพื่อรับค่า unicode

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

3
ฉันพยายามเรียงลำดับตัวอักษร - การคูณด้วย -1 ไม่ใช่การดำเนินการที่ถูกต้อง :)
rythos42

มันคุ้มค่าในขณะที่กรณีการใช้งาน แต่ไม่ได้ระบุไว้ในคำถาม อย่างไรก็ตามการคูณสตริงด้วย -1 เป็นการดำเนินการที่ถูกต้อง ส่งคืน NaN ซึ่งเป็นผลลัพธ์ที่ถูกต้อง
jEremyB

1
อย่าลืมกำหนดอาร์เรย์กลับด้วย! SOME_ARR = _.sortBy (SOME_ARR, ฟังก์ชั่น (จำนวน) {SOME_FUNC ... });
aqm

4
charCodeAt จะ "คืน Unicode ของตัวละครที่ดัชนีที่ระบุในสตริง" เพื่อให้สามารถใช้ในการจัดเรียงตามตัวอักษรในสตริง แต่ตามที่ปรากฏมันไม่ได้ "เรียงตามสตริง" มันเรียงลำดับตามตัวอักษรในสตริง
แอนโทนี

2
นี่เป็นเพียงการเรียงลำดับโดยตัวอักษรตัวแรกและเป็นกรณี ๆ ไป
Aidan

50

อาร์เรย์ต้นแบบของวิธีการย้อนกลับปรับเปลี่ยนอาร์เรย์และผลตอบแทนอ้างอิงกับมันซึ่งหมายความว่าคุณสามารถทำเช่นนี้:

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

นอกจากนี้เอกสารที่ขีดล่างอ่าน:

นอกจากนี้วิธีการของต้นแบบ Array นั้นถูกพร็อกซีผ่านวัตถุ Underscore ที่ถูกล่ามโซ่เพื่อให้คุณสามารถส่ง a reverseหรือ a pushไปยังห่วงโซ่ของคุณและทำการแก้ไขอาร์เรย์ต่อไป

ซึ่งหมายความว่าคุณสามารถใช้.reverse()ในขณะที่ผูกมัด:

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

นี่คือวิธีการที่ง่ายที่สุดสำหรับการจัดเรียงย้อนกลับ / จากบนลงในกรณีการใช้งานที่ง่ายที่สุด
Dan Atkinson

2
หากต้องการเรียงลำดับตามตัวอักษรตามตัวพิมพ์ใหญ่_.sortBy(collection, item => item. propertyName.toLowerCase());
XåpplI'-I0llwlg'I -

วิธีนี้ใช้ไม่ได้หากมีจำนวนลบในอาร์เรย์
Shruti Kapoor

@ShrutiKapoor ใช่แล้ว ทำไมถึงไม่ทำ?
Emil Lundberg

5
ประสิทธิภาพควรเลือกใช้ตัวกรองก่อนเพื่อเรียงลำดับ (ส่วนที่เหลือ)
สราญ

12

คล้ายกับไลบรารี Underscore มีไลบรารีอื่นที่เรียกว่า 'lodash' ซึ่งมีวิธีการหนึ่ง "orderBy" ซึ่งใช้ในพารามิเตอร์เพื่อกำหนดว่าจะเรียงลำดับอย่างไร คุณสามารถใช้มันเหมือน

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

ด้วยเหตุผลบางอย่างเอกสารดังกล่าวไม่ได้ถูกบันทึกไว้ในเอกสารของเว็บไซต์


ฉันคิดว่าคุณสับสนขีดกับlodash เฉพาะหลังมีการกล่าวถึงฟังก์ชั่น orderBy
โทมัสมาร์ติ

ใช่ฉันไม่ดี จะอัพเดตคำตอบ ขอบคุณสำหรับการแก้ไข :)
Minkesh Jain

orderByมีประโยชน์มาก! ดีกว่าการใช้ reverse เพราะมันรักษาคุณสมบัติการเรียงลำดับที่เสถียรที่ฉันกำลังมองหา
Flimm

ไม่ทำงานสำหรับฉันด้วยเหตุผลบางประการ upadte: lodash (
aleXela

0

ขีดเส้นใต้ Mixins

เมื่อเพิ่มคำตอบของ @ emil_lundberg คุณยังสามารถเขียน "mixin" หากคุณใช้ Underscore เพื่อสร้างฟังก์ชันที่กำหนดเองสำหรับการเรียงลำดับหากเป็นการเรียงลำดับที่คุณอาจทำซ้ำในแอปพลิเคชันบางแห่ง

ตัวอย่างเช่นคุณอาจมีตัวควบคุมหรือดูผลลัพธ์การเรียงลำดับที่มีการเรียงลำดับของ "ASC" หรือ "DESC" และคุณต้องการสลับระหว่างการเรียงลำดับนั้นคุณสามารถทำสิ่งนี้:

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

ตัวอย่างการใช้งาน

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

นี่คือ JSFiddle แสดงให้เห็นถึงสิ่งนี้: JSFiddle สำหรับ SortBy Mixin

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.