ไม่มีคำตอบใดที่เหมาะเป็นวิธีการทั่วไปสำหรับการใช้หลายช่องในการจัดเรียง วิธีการทั้งหมดข้างต้นไม่มีประสิทธิภาพเนื่องจากต้องเรียงลำดับอาร์เรย์หลาย ๆ ครั้ง (ซึ่งในรายการที่ใหญ่พออาจทำให้สิ่งต่างๆช้าลงได้มาก) หรือสร้างวัตถุขยะจำนวนมากที่ VM จะต้องล้างข้อมูล (และในที่สุดก็ช้าลง โปรแกรมลง).
นี่คือโซลูชันที่รวดเร็วมีประสิทธิภาพช่วยให้สามารถจัดเรียงย้อนกลับได้ง่ายและสามารถใช้ร่วมกับunderscore
หรือlodash
หรือโดยตรงกับArray.sort
ส่วนที่สำคัญที่สุดคือcompositeComparator
เมธอดซึ่งใช้อาร์เรย์ของฟังก์ชันตัวเปรียบเทียบและส่งคืนฟังก์ชันตัวเปรียบเทียบคอมโพสิตใหม่
/**
* Chains a comparator function to another comparator
* and returns the result of the first comparator, unless
* the first comparator returns 0, in which case the
* result of the second comparator is used.
*/
function makeChainedComparator(first, next) {
return function(a, b) {
var result = first(a, b);
if (result !== 0) return result;
return next(a, b);
}
}
/**
* Given an array of comparators, returns a new comparator with
* descending priority such that
* the next comparator will only be used if the precending on returned
* 0 (ie, found the two objects to be equal)
*
* Allows multiple sorts to be used simply. For example,
* sort by column a, then sort by column b, then sort by column c
*/
function compositeComparator(comparators) {
return comparators.reduceRight(function(memo, comparator) {
return makeChainedComparator(comparator, memo);
});
}
คุณจะต้องมีฟังก์ชันเปรียบเทียบเพื่อเปรียบเทียบเขตข้อมูลที่คุณต้องการจัดเรียง naturalSort
ฟังก์ชั่นจะสร้างเปรียบเทียบให้สนามโดยเฉพาะอย่างยิ่ง การเขียนตัวเปรียบเทียบสำหรับการเรียงลำดับย้อนกลับก็เป็นเรื่องเล็กน้อยเช่นกัน
function naturalSort(field) {
return function(a, b) {
var c1 = a[field];
var c2 = b[field];
if (c1 > c2) return 1;
if (c1 < c2) return -1;
return 0;
}
}
(รหัสทั้งหมดจนถึงตอนนี้สามารถใช้ซ้ำได้และสามารถเก็บไว้ในโมดูลยูทิลิตี้เป็นต้น)
ถัดไปคุณต้องสร้างตัวเปรียบเทียบคอมโพสิต สำหรับตัวอย่างของเราจะมีลักษณะดังนี้:
var cmp = compositeComparator([naturalSort('roomNumber'), naturalSort('name')]);
โดยจะเรียงตามหมายเลขห้องแล้วตามด้วยชื่อ การเพิ่มเกณฑ์การจัดเรียงเพิ่มเติมเป็นเรื่องเล็กน้อยและไม่มีผลต่อประสิทธิภาพของการจัดเรียง
var patients = [
{name: 'John', roomNumber: 3, bedNumber: 1},
{name: 'Omar', roomNumber: 2, bedNumber: 1},
{name: 'Lisa', roomNumber: 2, bedNumber: 2},
{name: 'Chris', roomNumber: 1, bedNumber: 1},
];
// Sort using the composite
patients.sort(cmp);
console.log(patients);
ส่งคืนสิ่งต่อไปนี้
[ { name: 'Chris', roomNumber: 1, bedNumber: 1 },
{ name: 'Lisa', roomNumber: 2, bedNumber: 2 },
{ name: 'Omar', roomNumber: 2, bedNumber: 1 },
{ name: 'John', roomNumber: 3, bedNumber: 1 } ]
เหตุผลที่ฉันชอบวิธีนี้คือช่วยให้สามารถจัดเรียงได้อย่างรวดเร็วในจำนวนฟิลด์โดยพลการไม่สร้างขยะจำนวนมากหรือทำการต่อสตริงภายในการจัดเรียงและสามารถใช้งานได้อย่างง่ายดายเพื่อให้บางคอลัมน์ถูกจัดเรียงแบบย้อนกลับในขณะที่คอลัมน์ลำดับใช้ natural ประเภท