あべてっく

役に立ったり立たなかったりする内容を備忘録的にちょこちょこと。
 

Javascriptの配列がキー値で自動ソートされてしまう件

投稿日 2013年5月24日  カテゴリ : Javascript ,JQuery  タグ :

たとえば、PHPなどで動的に生成される登録順(数値型)をキー値とした配列があるとします。

var ary = {1:”はげ”, 2:”ほげ”, 3:”ひげ”, 4:”ふげ”}

これを50音順でソートされた形のデータが欲しいとします。

var ary = {1:”はげ”, 3:”ひげ”, 4:”ふげ”, 2:”ほげ”}

しかしこの配列を実際に読み込ますと、自動でキー値でソートされてしまいます。

var ary = {1:”はげ”, 3:”ひげ”, 4:”ふげ”, 2:”ほげ”}

//// Jqueryのeachを使う
$.each(ary, function(i, val){
console.log(i+’:’+val);
});

//// for inを使う
for(i in ary){
console.log(i+’:’+ary[i]);
};

//// 結果
どっちもキー値順で出てくる
1:はげ
2:ほげ
3:ひげ
4:ふげ

以前はIE9やsafariなど特定のブラウザのみに発生する挙動の違いという扱いでしたが、最近では
ほぼ全てのメジャーなブラウザで起こるようになってますね。仕様ということでしょうか。
これを回避する方法を調べたのですがなかなかピンと来るのがありませんでした。
例ではひらがなだけを使用した単純な値4つのみですが、実際には漢字やアルファベットも混ざった結構な数のデータとなるので
単純にJavascript上で値でソートするというのは避け、配列生成する段階でなんとかしたいところです。
そうなると、

それぞれの要素を順番でラップする(順番情報を埋め込む)とか

var ary = {1:{1:”はげ”}, 2{3:”ひげ”}, 3:{4:”ふげ”}, 4:{2:”ほげ”}}

キーの頭にアンダースコア付けて、キー値が必要な時ははずしてやるとか

var ary = {_1:”はげ”, _3:”ひげ”, _4:”ふげ”, _2:”ほげ”}
$.each(ary, function(i, val){
console.log(i.replace(“_”, “”)+’:’+val);
});

こういうことになってしまいます。
既存の作成物のカスタマイズとなるので配列読み込みロジックの大幅変更は避けたいところですがまだいい方法見つかってません。
誰か解法かもん><

 
 

JavaScript 第6版
JavaScript 第6版

posted with amazlet at 13.06.20
David Flanagan
オライリージャパン
売り上げランキング: 5,670

 

2 Responses to Javascriptの配列がキー値で自動ソートされてしまう件

  1. ちよよ says:

    オブジェクトはそもそも順序を保証していないものです。
    pushやpopを備えてないので、間接的にですが保障していないことがわかります。
    ブラウザでもソートの挙動が変わるようなので、なおさらキーを順序にすることは避けた方がよいかと思います。
    [参考:ブラウザごとのキーのソート順]
    http://qiita.com/suguru03/items/bf48610225fefcb0f45e

    解決法として今思いつくところは以下ですかね

    1.配列にする(中身はソート済みにする)
    クエリにorder byをつけるか、usortなどで並び替えて送出。
    DB、Webのどちらに負荷をかけるのかなどによって選択が変わるかと思います。
    var ary = [”はげ”, ”ほげ”, ”ひげ”, ”ふげ”]
    var ary = [{"id":1, "value":”はげ”}, {"id":3, "value":”ひげ”}, {"id":4, "value":”ふげ”}, {"id":2, "value":”ほげ”}]

    2.既に記載されていますが、順番情報を埋め込む
    この時は、ちゃんとキーを付け加えたほうがいいかと思います。(Stackoverflowでもそのようになっているかと)
    ただ、並び替えがjavascritpになるため、要件に合わないかと思います。
    var ary = {1:{"sort":1, "value":”はげ”}, 2:{"sort":3, "value":”ひげ”}, 3:{"sort":4, "value":”ふげ”}, 4:{"sort":2, "value":”ほげ”}}

  2. あべ says:

    この記事を書いた当時はPHPとごっちゃになってたせいでわかんなかったのですが
    その後突然javascriptでのarrayとobjectの違いを理解しました。
    上のaryは配列だと思ってたのですが実はobjectだったんですね。(正確にはdictionaryですが)
    そっから一気に理解が進みました。
    var ary = [”はげ”, ”ほげ”, ”ひげ”, ”ふげ”]
    var obj = {1:”はげ”, 3:”ひげ”, 4:”ふげ”, 2:”ほげ”}

あべ へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です