이러한 답변 중 어느 것도 여러 필드를 한꺼번에 사용하기위한 범용 방법으로 이상적이지는 않습니다. 위의 모든 접근 방식은 배열을 여러 번 정렬해야하거나 (충분한 목록에서 많은 속도를 늦출 수 있음) 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 } ]
내가이 방법을 선호하는 이유는 임의의 수의 필드에 대해 빠른 정렬이 가능하고 많은 쓰레기를 생성하지 않거나 정렬 내에서 문자열 연결을 수행하지 않으며 일부 열이 역순으로 정렬되고 정렬 열이 자연적으로 사용되도록 쉽게 사용할 수 있기 때문입니다. 종류.