如何通过多个字段对对象数组进行排序?
从这个原始问题,我将如何应用在多个领域的排序?
使用这个稍微适应的结构,我将如何对城市(升序)和价格(降序)进行分类?
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"}
];
我喜欢这个事实,而不是给出一个通用方法的答案。 在计划使用这些代码的地方,我将不得不对日期和其他事物进行排序。 如果不是一点麻烦的话,“引发”对象的能力似乎很方便。
我试图将这个答案编译成一个很好的通用示例,但我没有太多运气。
基于这个答案的多维排序方法:
更新 :这是一个“优化”版本。 它做了更多的预处理,并为每个排序选项预先创建一个比较函数。 它可能需要更多的内存(因为它为每个排序选项存储了一个函数,但它应该更好一些,因为它不需要在比较过程中确定正确的设置,尽管我没有进行任何分析。
var sort_by;
(function() {
// utility functions
var default_cmp = function(a, b) {
if (a == b) return 0;
return a < b ? -1 : 1;
},
getCmpFunc = function(primer, reverse) {
var dfc = default_cmp, // closer in scope
cmp = default_cmp;
if (primer) {
cmp = function(a, b) {
return dfc(primer(a), primer(b));
};
}
if (reverse) {
return function(a, b) {
return -1 * cmp(a, b);
};
}
return cmp;
};
// actual implementation
sort_by = function() {
var fields = [],
n_fields = arguments.length,
field, name, reverse, cmp;
// preprocess sorting options
for (var i = 0; i < n_fields; i++) {
field = arguments[i];
if (typeof field === 'string') {
name = field;
cmp = default_cmp;
}
else {
name = field.name;
cmp = getCmpFunc(field.primer, field.reverse);
}
fields.push({
name: name,
cmp: cmp
});
}
// final comparison function
return function(A, B) {
var a, b, name, result;
for (var i = 0; i < n_fields; i++) {
result = 0;
field = fields[i];
name = field.name;
result = field.cmp(A[name], B[name]);
if (result !== 0) break;
}
return result;
}
}
}());
用法示例:
homes.sort(sort_by('city', {name:'price', primer: parseInt, reverse: true}));
DEMO
原始功能:
var sort_by = function() {
var fields = [].slice.call(arguments),
n_fields = fields.length;
return function(A,B) {
var a, b, field, key, primer, reverse, result, i;
for(i = 0; i < n_fields; i++) {
result = 0;
field = fields[i];
key = typeof field === 'string' ? field : field.name;
a = A[key];
b = B[key];
if (typeof field.primer !== 'undefined'){
a = field.primer(a);
b = field.primer(b);
}
reverse = (field.reverse) ? -1 : 1;
if (a<b) result = reverse * -1;
if (a>b) result = reverse * 1;
if(result !== 0) break;
}
return result;
}
};
DEMO
对于您的确切问题的非通用简单解决方案:
homes.sort(
function(a, b) {
if (a.city !== b.city) {
return b.price - a.price;
}
return a.city > b.city ? 1 : -1;
});
我今天做了一个非常通用的多功能分拣机。 你可以在这里看看thenBy.js:https://github.com/Teun/thenBy.js
它允许您使用标准的Array.sort,但使用firstBy()。thenBy()。thenBy()样式。 与上述解决方案相比,它的代码和复杂性要低得多
链接地址: http://www.djcxy.com/p/3233.html上一篇: How to sort an array of objects by multiple fields?
下一篇: How to sort an array of objects with multiple field values in JavaScript