从这个原始问题开始,我将如何对多个字段进行排序?
使用这种略微适应的结构,我该如何对城市(升序)和价格(降序)进行排序?
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}));
原始功能:
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; } };