2012-11-02 206 views
2

如何排序後面的對象以糾正字母順序名稱按屬性值排序javascript對象

var users_by_id = { 
    '12': ['Ted', 34, 'Male'], 
    '13': ['Ben', 36, 'Male'], 
    '14': ['Alice', 42, 'Female'] 
} 

var users_by_name = { 
    '14': ['Alice', 42, 'Female'], 
    '13': ['Ben', 36, 'Male'], 
    '12': ['Ted', 34, 'Male'] 
} 

我有一個計劃,需要兩次通過對象,但我不知道是否有一個更簡單的方法來做到這一點。我的計劃是這樣的(我使用jQuery):

var users_by_name = {}; 
var names = []; 
$.each(users_by_id, function(id, props) { 
    names.push(props[0]); 
}); 
names.sort(); 
$.each(names, function(i, n) { 
    $.each(users_by_id, function(id, props) { 
    if(n == props[0]) users_by_name[id] = props; 
    }); 
}); 
+5

你的數組是一個對象看一看,和對象有沒有順序。你是否希望最終獲得陣列陣列? –

+1

http://stackoverflow.com/questions/1069666/sorting-javascript-object-by-property-value – Ana

+0

@ user1689607,你是對的!我測試了這個,結果如下:http://jsbin.com/ehinec/1/但是,我不知道爲什麼使用Firebug,console.log條目的順序意味着對象*有*順序。 –

回答

0

排序有一個可選的參數,它是一個比較功能 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort

var data =[ 
    ['Ted', 34, 'Male'], 
    ['Ben', 36, 'Male'], 
    ['Alice', 42, 'Female'] 
]; 

var sortbyid = data.sort(function(a,b){return a[1]<b[1] ? -1 : a[1]>b[1] ? 1 : 0}); 
var sortbyname = data.sort(function(a,b){return a[0]<b[0] ? -1 : a[0]>b[0] ? 1 : 0}); 
+1

這個人想排序和對象 - 這是不可能的,對象不能排序。你的例子很有用,但它與Array相關。 – Reflective

3

如果你想保持你的基於對象的存儲,而不是使用數組,您需要創建對象屬性的數組,然後對其進行排序以獲得訂單。

var users = { 
    '12': ['Ted', 34, 'Male'], 
    '13': ['Ben', 36, 'Male'], 
    '14': ['Alice', 42, 'Female'] 
}; 

var props = Object.keys(users); 

var user_props_by_name = props.slice().sort(function(prop_a, prop_b) { 
    return users[prop_a][0].localeCompare(users[prop_b][0]); 
}); 

var user_props_by_age = props.slice().sort(function(prop_a, prop_b) { 
    return users[prop_a][1] - users[prop_b][1]; 
}); 

然後你可以遍歷數組,並使用屬性名來查找項目的對象。

user_props_by_name.forEach(function(prop) { 
    console.log(users[prop]); 
}); 

user_props_by_age.forEach(function(prop) { 
    console.log(users[prop]); 
}); 

雖然添加和刪除用戶時需要一些維護。您可能希望創建一個添加和刪除用戶的圖層,並同時更新排序數組。

0

排序通常是在迭代集合時進行的。所以......我的建議是將方法添加到對象的原型 - .keysById.keysByName,它們必須返回按上述條件排序的按鍵。所以當你必須按名稱迭代時:

var kbn = yourObj.keysByName(); 
for(var i=0; i<yourObj.length;i++) { 
    ... yourObj[kbn[i]] .... 
} 

你可以做這個方法,我敢肯定,所以我不會舉例。

yourObj.prototype.keysByName = function() { ... } 
0

好的,我明白了。正如評論中指出的那樣,對象沒有任何順序。因此,無論以什麼順序添加(或定義)成員,迭代該對象將產生the same result

所以,我應該改變我的方法。有一點背景是需要看看爲什麼新方法會起作用(順便說一下,這個問題在這個問題上是沒有的)。

我有一個用戶表,我想以字母順序顯示與用戶的HTML表所示:

<tr id="user-N"><td>NAME</td><td>AGE</td><td>GENDER</td></tr> 

而且這裏是我來過:

var name_ids = []; 
var trows = '', thisNID; 
$.each(users_by_id, function(id, props) { 
    name_ids.push(props[0]+':'+id); 
}); 
name_ids.sort(); 
$.each(name_ids, function(i,nid) { 
    thisNID = nid.split(':'); 
    trows += '<tr id="user-' + thisNID[1] + '">'; 
    trows += '<td>' + users_by_id[thisNID[1]][0] + '</td>'; 
    trows += '<td>' + users_by_id[thisNID[1]][1] + '</td>'; 
    trows += '<td>' + users_by_id[thisNID[1]][2] + '</td>'; 
    trows += '</tr>'; 
}); 
+0

事實證明我提出了錯誤的問題,如果沒有對意圖的補充說明,就不可能有類似的答案。那麼我不打算將這個答案標記爲已接受的答案。 –

+0

最終結果如下:http://jsbin.com/ehinec/4/edit –

0

另一個選項利用Array.prototype。排序函數

var users_by_id = { 
     '0': ['Ted', 34, 'Male'], 
     '1': ['Ben', 36, 'Male'], 
     '2': ['Alice', 42, 'Female'] 
} 

// as long as length is bigger than max object key value 
users_by_id.length = Object.keys(users_by_id).length; 

Array.prototype.sort.call(users_by_id, function(a, b) { 

     var aName = a[0].toLowerCase(); 
     var bName = b[0].toLowerCase(); 

     if(aName > bName) return 1; 
     if(aName < bName) return -1; 
     return 0; 
}); 

有幾個告誡上述:

  1. 該對象必須包含一個長度屬性
  2. length屬性必須具有的值大於max較大對象鍵

如果您不使用連續數字作爲鍵並執行以下操作:

var users_by_id = { 
      '12': ['Ted', 34, 'Male'], 
      '13': ['Ben', 36, 'Male'], 
      '14': ['Alice', 42, 'Female'] 
    } 

一旦排序對象的排序的數字鍵將被重新命名=> 0,1,2

在小提琴here