2013-05-20 159 views
16

我有一个按名称排序的函数和一个值/密钥对的数组。对键值排序数组

我不知道如何可以通过在其上进行排序,所以我可以调用同一个函数每次像这样一次关键:

var arr = [{name:'bob', artist:'rudy'}, 
      {name:'johhny', artist:'drusko'}, 
      {name:'tiff', artist:'needell'}, 
      {name:'top', artist:'gear'}]; 

sort(arr, 'name'); //trying to sort by name 
sort(arr, 'artist'); //trying to sort by artist 

function sort(arr) { 
    arr.sort(function(a, b) { 
    var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase(); 
    if (nameA < nameB) //sort string ascending 
     return -1; 
    if (nameA > nameB) 
     return 1; 
    return 0; //default return value (no sorting) 
    });   
} 
+0

添加标签, –

+0

JavaScript中,通过它的外观。 –

+0

这是一个重复的问题:http://stackoverflow.com/questions/5421253/sort-javascript-array-of-objects-based-on-one-of-the-objects-properties – Xavier

回答

19

这里有两个排序功能可能有用:

// sort on values 
function srt(desc) { 
    return function(a,b){ 
    return desc ? ~~(a < b) : ~~(a > b); 
    }; 
} 

// sort on key values 
function keysrt(key,desc) { 
    return function(a,b){ 
    return desc ? ~~(a[key] < b[key]) : ~~(a[key] > b[key]); 
    } 
} 

对于数组您可以排序的 '名称' 使用:

var arr = [ {name:'bob', artist:'rudy'} 
      ,{name:'johhny', artist:'drusko'} 
      ,{name:'tiff', artist:'needell'} 
      ,{name:'top', artist:'gear'}] 
      .sort(keysrt('name')); 

您还可以结合排序功能:

function srt(desc,key) { 
return function(a,b){ 
    return desc ? ~~(key ? a[key]<b[key] : a < b) 
       : ~~(key ? a[key] > b[key] : a > b); 
    }; 
} 

并使用

var arr = [ {name:'bob', artist:'rudy'} 
       ,{name:'johhny', artist:'drusko'} 
       ,{name:'tiff', artist:'needell'} 
       ,{name:'top', artist:'gear'}] 
       .sort(srt(null,'name')); 

这里是一种全在一个解决方案:

function srt(on,descending) { 
on = on && on.constructor === Object ? on : {}; 
return function(a,b){ 
    if (on.string || on.key) { 
    a = on.key ? a[on.key] : a; 
    a = on.string ? String(a).toLowerCase() : a; 
    b = on.key ? b[on.key] : b; 
    b = on.string ? String(b).toLowerCase() : b; 
    // if key is not present, move to the end 
    if (on.key && (!b || !a)) { 
     return !a && !b ? 1 : !a ? 1 : -1; 
    } 
    } 
    return descending ? ~~(on.string ? b.localeCompare(a) : a < b) 
        : ~~(on.string ? a.localeCompare(b) : a > b); 
    }; 
} 
// usage examples 
'a,z,x,y,a,b,B,Z,a,i,j,y'.split(',').sort(srt({string:true;})); 
//=> ,a,a,b,B,i,j,x,y,y,z,Z 
[100,7,8,2,2,0,5,1,6,5,-1].sort(srt()); 
//=> -1,0,1,2,2,5,5,6,7,8,100 
[100,7,8,2,2,0,5,1,6,5,-1].sort(srt({},true})); 
//=> 100,8,7,6,5,5,2,2,1,0,-1 
var objarr = 
[ {name:'bob', artist:'rudy'} 
    ,{name:'Johhny', artist:'drusko'} 
    ,{name:'Tiff', artist:'needell'} 
    ,{name:'top', artist:'gear'}] 
.sort(srt({key:'name',string:true}, true)); 
for (var i=0;i<objarr.length;i+=1) { 
    console.log(objarr[i].name); 
} 
//=> logs zeb, top, Tiff, Johnny consecutively 
+0

你也可以为数字排序做这项工作吗? – Toniq

+0

嗨@Toniq,看到编辑答案。 – KooiInc

+0

我的错误,你的初步答案实际上适用于数字排序(我只有字符串而不是数字)。我的下一个问题是如果某些数组项目中缺少关键值,我将如何将这些项目放在搜索列表的末尾? (所以可以说你按'艺术家'排序,但第二个数组项没有'艺术家'键值)谢谢 – Toniq

39
Array.prototype.sortOn = function(key){ 
    this.sort(function(a, b){ 
     if(a[key] < b[key]){ 
      return -1; 
     }else if(a[key] > b[key]){ 
      return 1; 
     } 
     return 0; 
    }); 
} 



var arr = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}]; 

arr.sortOn("name"); 
arr.sortOn("artist"); 
+2

比上面更优雅的解决方案! –

+1

同意。更多优雅和简单的解决方案。应该标记为正确的答案。做得好! –

+0

我知道这是旧的,但要注意,这个算法会在“宇航员”之前排序“独角兽”,因为大写字母的ASCII值小于小写字母(至少我认为这就是为什么) – Wade

5
function keysrt(key) { 
    return function(a,b){ 
    if (a[key] > b[key]) return 1; 
    if (a[key] < b[key]) return -1; 
    return 0; 
    } 
} 

someArrayOfObjects.sort(keysrt('text')); 
+0

这对最新的Chrome很好用。 – dvdplm

+1

看起来像二极管的答案(但从原型中删除)的重复,应该可能会被删除。此外,请注意,这种算法会在“宇航员”之前对“独角兽”进行排序,因为大写字母的ASCII值小于小写字母(至少我认为这就是为什么:) – Wade

0

看着都答案,我想出了我自己的跨浏览器的解决方案。接受的解决方案在IE或Safari中不起作用。另外,其他解决方案不允许按降序排序。

/*! FUNCTION: ARRAY.KEYSORT(); **/ 
Array.prototype.keySort = function(key, desc){ 
    this.sort(function(a, b) { 
    var result = desc ? (a[key] < b[key]) : (a[key] > b[key]); 
    return result ? 1 : -1; 
    }); 
    return this; 
} 

var arr = [{name:'bob', artist:'rudy'}, {name:'johhny', artist:'drusko'}, {name:'tiff', artist:'needell'}, {name:'top', artist:'gear'}]; 
arr.keySort('artist'); 
arr.keySort('artist', true); 
+0

https://stackoverflow.com/a/16649079/4796321允许降序排序。 – timmyRS

1

让你的生活方便,使用封闭 https://stackoverflow.com/a/31846142/1001405

你可以看到工作示例语言here

var filter = 'name', //sort by name 
data = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}];; 

var compare = function (filter) { 
    return function (a,b) { //closure 
     var a = a[filter], 
      b = b[filter]; 

     if (a < b) { 
      return -1; 
     }else if (a > b) { 
      return 1; 
     } else { 
      return 0; 
     } 
    }; 
}; 

filter = compare(filter); //set filter 

console.log(data.sort(filter)); 
+0

为什么这会让生活变得更轻松?请解释。 – Wade