从它的内容来看,这听起来很简单,但我还没有成功地在Chrome中取得完美的成绩(我在IE中做到了)
所以我有一个对象:
var objs=[
{ name: "water", type: "cold" },
{ name: "tea", type: "hot" },
{ name: "coffee", type: "hot" },
{ name: "choco", type: "cold" }
];
我按名称排序,升序,我得到了预期的结果:
我在IE和Chrome中都得到了相同的结果,
然后,我按类型,升序和期望再次对其进行排序:
但是我只在IE中获得了预期的结果,而在Chrome中,结果几乎相同,除了" water"来到顶部(它破坏了第一次排序)
任何一般方法的想法? (我需要为每个字段保留一个函数调用,而不是同时在一个函数中按多个字段排序)
我的排序方法是这样的:
function SortBy(key,Asc,method){
var GetKey=function(x) {return method ? method(x[key]) : x[key] };
return function(a,b){
var A=GetKey(a), B=GetKey(b);
return ((A<B) ? -1 : ((A>B) ? 1 : 0)) * [-1,1][+!!Asc];
}
}
var sortedObjects=Clone(objs); //clone the current objs
sortedObjects.sort(SortBy("name" , true, function(x){
if (typeof(x)=="string") return x.toLowerCase(); else return x;
}));
objs=sortedObjects; //got the first result
sortedObjects.sort(SortBy("type",true,function(x){
if (typeof(x)=="string") return x.toLowerCase(); else return x;
}));
objs=sortedObjects;
已编辑这里是小提琴(问题是&#34; Water&#34;):DEMO
答案 0 :(得分:1)
如果我们阅读 ES5规范 §15.4.4.11 Array.prototype.sort,则第二句话说明
排序不一定稳定(也就是说,比较相等的元素不一定保持原始顺序)
也就是说,在 JavaScript 中,如果比较器说两件事情是相等的(通过给出0
),那么它们是否被交换并不重要。因此,在某些环境中,由于某些其他原因(例如哈希或仅实施),它们可能会交换。
即。您遇到的结果是由规范定义的sort
的有效结果,并且重复相同的sort
甚至可能每次都会给出不同的结果
希望我不会为此付出过多的代价,但如果你把它作为一个功能那么做,那么你就不需要多次遍历数组而你将避免意外结果
/* list = multiSort(list [, obj, ...])
* where e.g. obj = {
* key: "keyToLookAt",
* optional comparator: function (a, b) {return a<b || ((a===b)-1);},
* optional ascending: default true
* }
*/
var multiSort = (function () {
function generateSorter(key, comparator, ascending) {
ascending = 2 * !!ascending - 1;
if (comparator) {
return function sorter(a, b) {
return ascending * comparator(a[key], b[key]);
};
}
return function sorter(a, b) {
a = a[key];
b = b[key];
return ascending * (a < b ? -1 : a > b ? 1 : 0);
};
}
function sortManager(sorters) {
return function (a, b) {
var ret, i = 0;
for (; i < sorters.length; ++i) {
ret = sorters[i](a, b);
if (ret !== 0) return ret;
}
return 0;
};
}
function multiSort(list) {
var i = 1, sorters = [];
for (; i < arguments.length; ++i) {
sorters.push(generateSorter(
arguments[i].key,
arguments[i].comparator,
'ascending' in arguments[i] ? arguments[i].ascending : 1
));
}
list.sort(sortManager(sorters));
return list;
}
return multiSort;
}());
然后在使用它时,最严格的&#34;排序规则首先
multiSort(
[
{ name: "water", type: "cold" },
{ name: "tea", type: "hot" },
{ name: "coffee", type: "hot" },
{ name: "choco", type: "cold" }
],
{key: 'type'},
{key: 'name'}
);
/*
[
{ "name": "choco" , "type": "cold" },
{ "name": "water" , "type": "cold" },
{ "name": "coffee", "type": "hot" },
{ "name": "tea" , "type": "hot" }
]
*/
答案 1 :(得分:0)
我创建了一个CodePen来测试并正常工作...... 我用更易读的代码写了相同的想法
function SortBy(key, isAsc, fn){
fn = fn || function (x){ return x; };
return function(objA, objB){
var a = fn(objA[key]);
var b = fn(objB[key]);
var isGreater = isAsc ? 1 : -1;
var isLesser = -isGreater;
var isSame = 0;
if( a > b ) return isGreater;
if( a == b ) return isSame;
if( a < b ) return isLesser;
return -1; //to down the undefined
}
}
http://codepen.io/anon/pen/sGgDq使用大量数据进行了编辑和测试
p.s。:我使用了codepen,因为jsfiddle在我的工作中没有打开