あなたavatars
は配列ではなく、単なるオブジェクトです:
avatars = {};
したがって、その要素の順序は定義されていません。
プロパティを列挙するメカニズムと順序(最初のアルゴリズムのステップ6.a、2番目のアルゴリズムのステップ7.a)は指定されていません。
および15.2.3.7(および15.2.3.14):
実装がfor-inステートメントの列挙の特定の順序を定義する場合、このアルゴリズムのステップ3でリスト要素を順序付けるために、同じ列挙順序を使用する必要があります。
セクション8.6をチェックして、オブジェクト内のプロパティの順序についての言及があるかどうかを確認することもできます。オブジェクトプロパティの順序付けの唯一の要件は、実装がどこでも順序を定義する場合、どこでも同じ順序を使用する必要があるということですが、それは大きな場合です。ほとんどの実装はおそらくオブジェクトのキーの挿入順序を使用しますが、それらを必要とするものは見つかりません(オブジェクトのキーの特定の順序を定義する仕様で誰かが何かを指摘できる場合はコメントをいただければ幸いです)。
とは言うものの、アンダースコアsortBy
は基本的にシュワルツ変換sort
であり、標準のJavaScriptとアンダースコアを組み合わせてpluck
シュワルツ変換のメモラッパーをアンラップします。pluck
配列を返すので、配列sortBy
も返します。したがって、最後の_.keys(avatars)
呼び出しは実際_.keys
には配列を呼び出しています。配列のキー(別名列挙可能なプロパティ)は配列のインデックスであり、それらはゼロから始まる連続した整数です。
間違ったデータ構造を使用しています。スパース配列が必要であるが、配列のように操作する(つまり、並べ替える)必要がある場合は、オブジェクト内にインデックスを配置し、次pluck
の代わりに通常の配列を使用する必要がありkeys
ます。
var avatars = [
{idx: 102, userInfo: {buddy_name: 'Avatar102', is_online: 1}},
{idx: 100, userInfo: {buddy_name: 'Avatar100', is_online: 1}},
{idx: 101, userInfo: {buddy_name: 'Avatar101', is_online: 1}}
];
console.log(_(avatars).pluck('idx'));
avatars = _(avatars).sortBy(function(avatar) {
return avatar.userInfo.buddy_name.toLowerCase();
});
console.log(_(avatars).pluck('idx'));
デモ: http: //jsfiddle.net/ambiguous/UCWL2/
それまでに迅速なアクセスも必要な場合は、直接アクセスidx
用の並列オブジェクトを設定できます。idx
var avatars_by_idx = { };
for(var i = 0; i < avatars.length; ++i)
avatars_by_idx[avatars[i].idx] = avatars[i];
次にavatars_by_idx
、探している直接アクセスを提供します。もちろん、同期を維持する必要がありますがavatars
、avatars_by_idx
両方をオブジェクトの背後に隠せば、それほど難しくはありません。