2013-05-20 197 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