2

名前のアルファベット順を修正するには、次のオブジェクトをどのように並べ替えますか?

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']
}

オブジェクトを 2 回通過する必要がある計画がありますが、それを行うためのより簡単な方法があるかどうかはわかりません。私が持っている計画はこれです(私は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;
  });
});
4

5 に答える 5

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]);
});

ただし、ユーザーを追加および削除するときに、これにはいくらかのメンテナンスが必要です。ユーザーを追加および削除し、同時に並べ替え配列を更新するレイヤーを作成することをお勧めします。

于 2012-11-03T00:12:35.280 に答える
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});
于 2012-11-03T00:07:14.197 に答える
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. 長さプロパティには、オブジェクト キーの最大より大きい値が必要です

連続した番号をキーとして使用せず、次の操作を行う場合:

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

ソートされると、オブジェクトのソートされた数値キーの名前が変更されます => 0,1,2

ここでフィドルを見てください

于 2012-11-03T02:34:52.643 に答える
0

はい、分かりました。コメントで指摘されているように、オブジェクトには順序がありません。そのため、メンバーが追加 (または定義) された順序に関係なく、オブジェクトを反復しても同じ結果が生成されます。

だから、私は私のアプローチを変更する必要があります。新しい方法が機能する理由を確認するには、少し背景が必要です (ちなみに、これは質問にはありません)。

ユーザーテーブルがあり、次のようにアルファベット順にユーザーを含む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>';
});
于 2012-11-03T00:51:47.547 に答える
0

並べ替えは通常、コレクションを反復処理する必要がある場合に行われます。だから...私の提案は、オブジェクトのプロトタイプにメソッドを追加することです-.keysByIdそして、.keysByName上記の条件によって順序付けられたキーを返す必要があります。したがって、名前で反復する必要がある場合は、次のことができます。

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

あなたはこの方法を行うことができると確信しているので、例を挙げません。

yourObj.prototype.keysByName = function() { ... }
于 2012-11-03T00:28:58.860 に答える