2015/11/20

Chromeでjsonのkeyを数字にしている場合、勝手に昇順にされる件

筆者環境:MacOSX Yosemite, Google Chromeバージョン 46.0.2490.86 (64-bit)
表題通り、ありがた迷惑な機能。
これはV8 JavaScript EngineのECMAScript準拠でバグではない模様。
5年前くらい前から変わっていない。
firefoxでは降順ソートは維持され、問題ないことを確認。

問題のIssue 37404 - chromium - Chrome reorders keys in the dictionary (object) http://bit.ly/1Qw0utr

こんな感じに成形して、keyを数字で降順ソートしたが、勝手にkeyで昇順にソートされる。
{
    1444275582: {
        url: "https://instagram.com/p/8j9S8_r_BE/",
        img: "https://scontent.cdninstagram.com/hphotos-xap1/t51.2885-15/s640x640/sh0.08/e35/12120292_917670381655742_1569021259_n.jpg"
    },
    1444545530: {
        url: "https://instagram.com/p/8sALlWAfUJ/",
        img: "https://scontent.cdninstagram.com/hphotos-xtp1/t51.2885-15/e15/12106290_1294775143882158_1454631624_n.jpg"
    }
}

対策

created_atのkeyだけで降順ソートでjson成形
{
    {
        created_at: "1447984282",
        url: "https://instagram.com/p/-SfFKzy73D/",
        img: "https://scontent.cdninstagram.com/hphotos-xfp1/t51.2885-15/       s640x640/sh0.08/e35/12256594_516826635166064_1483786264_n.jpg"
    },
    {
        created_at: "1447984163",
        url: "https://instagram.com/p/-Se2neyurm/",
        img: "https://scontent.cdninstagram.com/hphotos-xfp1/t51.2885-15/e15/12230899_1538400876451449_364138165_n.jpg"
    }
}

解決方法

バックエンド側でjsonを吐き出す実装を変える(php)



         // APIから取得したデータを成形
        foreach($result["data"] as $k => $v){
            $insta_arr[$k]["created_at"] =  $v["created_time"];
            $insta_arr[$k]["url"] =  $v["link"];
            $insta_arr[$k]["img"] =  $v["images"]["standard_resolution"]["url"];            
            //いったんソートするキーを配列で取り出して、            
            $created_at_arr[$k] = $v["created_time"];
        }

        // keyで降順
        array_multisort($created_at_arr ,SORT_DESC,$insta_arr);
        echo json_encode($insta_arr);
        exit;

js側でソート(lodash)

    _.map(_.sortByOrder(insta_arr, ['created_at'], ['desc']), _.values);

参考

Issue 37404 - chromium - Chrome reorders keys in the dictionary (object) http://bit.ly/1Qw0utr
Issue 164 - v8 - Wrong order in Object properties interation - V8 JavaScript Engine
https://code.google.com/p/v8/issues/detail?id=164
Google Chromeでjsonオブジェクトを扱う際に、勝手にキーでソートされたよ
http://log.miraoto.com/2013/02/738/