10

かなり複雑なJSONオブジェクトを返すajax呼び出しがあり、並べ替えに苦労しています。

私の電話:

$.post('/reports-ajax',arguments, function(data) {}

応答:

{
"10001":{
    "unitname":"Fort Worth",
    "discounts":{"12-02-2012":"34.810000","12-03-2012":"20.810000","12-04-2012":"27.040000"},
    "gross":{"12-02-2012":"56.730000","12-03-2012":"19.350000","12-04-2012":"66.390000"},
    "net":{"12-02-2012":"61.920000","12-03-2012":"98.540000","12-04-2012":"39.350000"},
    "discounts_total":82.66,
    "gross_total":82.47,
    "net_total":99.81,
    "number":10001
    },
"10002":{
    "unitname":"Dallast",
    "discounts":{"12-02-2012":"12.600000","12-03-2012":"25.780000","12-04-2012":"47.780000","12-05-2012":"45.210000"},
    "gross":{"12-02-2012":"29.370000","12-03-2012":"91.110000","12-04-2012":"60.890000","12-05-2012":"51.870000"},
    "net":{"12-02-2012":"16.770000","12-03-2012":"65.330000","12-04-2012":"13.110000","12-05-2012":"06.660000"},
    "discounts_total":131.37,
    "gross_total":33.24,
    "net_total":101.87,
    "number":10002
    },
"32402":{
    "unitname":"Austin",
    "discounts":{"12-05-2012":"52.890000","12-02-2012":"22.430000","12-03-2012":"58.420000","12-04-2012":"53.130000"},
    "gross":{"12-05-2012":"25.020000","12-02-2012":"2836.010000","12-03-2012":"54.740000","12-04-2012":"45.330000"},
    "net":{"12-04-2012":"92.200000","12-05-2012":"72.130000","12-02-2012":"13.580000","12-03-2012":"96.320000"},
    "discounts_total":186.87,
    "gross_total":161.1,
    "net_total":174.23,
    "number":32402
    }
}

私は標準の各呼び出しで関数を調べ、highchartsでいくつかの素晴らしいことをしますが、今はnet_total呼び出しで応答をソートしようとしているので、それを理解できません。

試し.sort()てみましたが、機能ではないというエラーが発生しました。私はしばらく読んでいますが、正しい結果が見つからないと思います。これは有望に見えました:JavaScriptオブジェクトの配列をソートし.sortましたが、isnot関数で失敗しました。ほとんど.sortが完全なオブジェクトではなく[]配列上にあるようです。

どんな助けでも大歓迎です。

4

2 に答える 2

16

オブジェクト キーには位置値がないため、オブジェクトの並べ替えは意味がありません。たとえば、次のようになります。

{ a:1, b:2 }

この:

{ b:2, a:1 }

はまったく同じオブジェクトです。似ているだけでなく、同じです。

javascript自体には、オブジェクトキーに位置値を与えるものは何もありません。一部の人々は、おそらく次のように誤解しています。

for (var key in obj) {

特定の順序でオブジェクト キーを反復処理します。しかし、これは間違っています。for .. inループはオブジェクト キーを常にランダムな順序で処理すると想定する必要があります。

for .. in明らかに、Web ブラウザーを作成する場合は、ループを解析するために乱数ジェネレーターを実装するつもりはありません。したがって、ほとんどの Web ブラウザでは、ループがオブジェクト キーを処理する方法が偶発的に安定しています。for .. in

ブラウザをいじって JavaScript を学習した開発者は、たとえば、ブラウザがオブジェクトをアルファベット順、またはキーがオブジェクトに追加された順序で繰り返し処理することに気付くかもしれません。しかし、これは完全に偶然であり、信頼することはできません。ブラウザー ベンダーは、下位​​互換性を損なうことなく、将来この動作を変更する可能性があります (ただし、オブジェクトに並べ替え順序があると信じている人々によって記述されたバグのあるスクリプトは除きます)。ブラウザーが異なれば JavaScript の実装も異なるため、必ずしもオブジェクトの内部キーの順序が同じであるとは限りません。

上記のすべては要点のほかです。「キーのソート順」は JavaScript では意味がなく、観察される動作は実装の詳細にすぎません。つまり、javascript オブジェクトにはキーの順序がなく、ランダムであると想定してください。


解決

ここで、実際にやろうとしているのは、オブジェクトを並べ替えないことです (できません。意味がありません)。あなたが実際にやろうとしているのは、オブジェクトの属性を特定の順序で処理することです。解決策は、オブジェクト キーの配列 (並べ替え順序を持つ) を作成し、その配列を使用してオブジェクトを処理することです。

// First create the array of keys/net_total so that we can sort it:
var sort_array = [];
for (var key in Response) {
    sort_array.push({key:key,net_total:Response[key].net_total});
}

// Now sort it:
sort_array.sort(function(x,y){return x.net_total - y.net_total});

// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
    var item = Response[sort_array[i].key];

    // now do stuff with each item
}
于 2012-12-07T07:25:15.557 に答える
6

あなたが持っているものには配列がなく、順序もありません。そのため、順序を付けることができるように、配列に変換する必要があります。

漠然と:

var array = [];
$.each(data, function(key, value) {
    array.push(value);
});
array.sort(function(a, b) {
    return a.net_total - b.net_total;
});

実例| ソース

GolezTroiがコメントで指摘しているように、通常、上記は各エントリが保存されているキーを失うため、上記dataの最初のループに追加し直します$.eachが、この場合、エントリにはすでにキーがあります(number)、必要はありません。

$.eachまたは、最初のものを$.map:に置き換えることができます

var array = $.map(data, function(entry) {
    return entry;
});
// ...and then sort etc.

...お好みの方。

于 2012-12-07T07:07:18.023 に答える