按属性值排序javascript对象

时间:2012-11-02 23:59:12

标签: javascript sorting

如何对以下对象进行排序以更正名称的字母顺序

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 个答案:

答案 0 :(得分: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]);
});

在添加和删除用户时,这将需要一些维护。您可能希望创建一个添加和删除用户的图层,并同时更新排序数组。

答案 1 :(得分:0)

sort接受一个可选参数,它是一个比较函数 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});

答案 2 :(得分:0)

通常在必须迭代集合时进行排序。所以...我的建议是广告你的对象原型的方法 - .keysById.keysByName必须返回按照上面提到的条件排序的键。因此,当您必须按名称进行迭代时,您可以执行以下操作:

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

你可以这样做,我敢肯定,所以我不会举例。

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

答案 3 :(得分: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>';
});

答案 4 :(得分:0)

另一个使用Array.prototype.sort函数的选项

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
  3. 如果您不使用连续数字作为键并执行以下操作:

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

    一旦排序,对象的排序数字键将被重命名=&gt; 0,1,2

    看看小提琴here