JavaScript在Chrome中通过多个字段对对象数组进行排序
从它所说的,这听起来很简单,但我没有成功地在Chrome上实现完美的效果(我是在IE上实现的) 所以我有一个目标:JavaScript在Chrome中通过多个字段对对象数组进行排序,javascript,google-chrome,sorting,Javascript,Google Chrome,Sorting,从它所说的,这听起来很简单,但我没有成功地在Chrome上实现完美的效果(我是在IE上实现的) 所以我有一个目标: var objs=[ { name: "water", type: "cold" }, { name: "tea", type: "hot" }, { name: "coffee", type: "hot" }, { name: "choco", type: "cold" } ]; 我按名称升序排序,得到了预期结果: 巧克力,冷的 热咖啡 茶,热的 冷水 我在IE和Chrome上
var objs=[
{ name: "water", type: "cold" },
{ name: "tea", type: "hot" },
{ name: "coffee", type: "hot" },
{ name: "choco", type: "cold" }
];
我按名称升序排序,得到了预期结果:
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;
功能排序(键、Asc、方法){
var GetKey=function(x){returnmethod?method(x[key]):x[key]};
返回函数(a,b){
变量A=GetKey(A),B=GetKey(B);
返回((AB)?1:0))*[-1,1][+!!Asc];
}
}
var sortedObjects=克隆(objs)//克隆当前对象
sortedObjects.sort(排序方式(“名称”),true,function(x){
if(typeof(x)=“string”)返回x.toLowerCase();else返回x;
}));
objs=分类对象//得到第一个结果
sortedObjects.sort(排序方式(“类型”),true,function(x){
if(typeof(x)=“string”)返回x.toLowerCase();else返回x;
}));
objs=分类对象;
编辑这里是小提琴(问题是“水”):如果我们阅读ES5规范,第二句话会说
排序不一定是稳定的(即,比较相等的元素不一定保持其原始顺序)
也就是说,在JavaScript中,如果比较器说两件事是相等的(通过给出0
),那么它们是否被交换并不重要,因此在某些环境中,它们可能会由于其他原因而被交换,例如它们的哈希或只是实现
i、 e.您体验到的结果是规范定义的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;
}());
我创建了一个代码笔来测试和工作良好。。。 我用可读性更强的代码写了同样的想法
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
}
}
功能排序(键、isAsc、fn){
fn=fn | |函数(x){返回x;};
返回函数(objA、objB){
var a=fn(objA[关键]);
var b=fn(objB[关键]);
var Ismorer=isAsc?1:-1;
var isLesser=-ismore;
var IsName=0;
如果(a>b)返回值更大;
如果(a==b),返回ISNAME;
如果(a
用大量数据编辑和测试
p、 s:我使用codepen是因为JSFIDLE在我的工作中没有打开你能创建一个小提琴吗?这在google chrome中对我很有用。你可以发布一个JSFIDLE或其他东西吗?为什么
需要为每个字段保留一个函数调用?这种低效我会创建一个提琴,显然它是有效的(我使用了样本数据),如果我使用更多的数据,那么它将不起作用您期望的结果不是您根据规范可以假设的结果,请查看对我答案的最后一次编辑显然我的样本数据只有4个数据它工作正常,我在提琴中获得了更多数据,在chrome中排序时出现错误。请发送小提琴:D,对我来说,处理大量数据效果很好,如果我发现问题,我会修复。如果在chrome和IE中打开它,输出会有所不同(我希望结果与IE中的一样)
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
}
}