36

私は次のように私のJSONを持っています

{"DATA": [{"id":11,"name":"ajax","subject":"OR","mark":63},
{"id":12,"name":"javascript","subject":"OR","mark":63},
{"id":13,"name":"jquery","subject":"OR","mark":63},
{"id":14,"name":"ajax","subject":"OR","mark":63},
{"id":15,"name":"jquery","subject":"OR","mark":63},
{"id":16,"name":"ajax","subject":"OR","mark":63},
{"id":20,"name":"ajax","subject":"OR","mark":63}],"COUNT":"120"}

distinct nameこのJSONから見つける良い方法はありますか

結果javascript,jquery,ajax

次のメソッドを使用してこれを行うことができます

var arr=[''];
var j=0;
for (var i = 0; i < varjson.DATA.length; i++) {
  if($.inArray(varjson.DATA[i]["name"],arr)<0){
      arr[j]=varjson.DATA[i]["name"];
      j++;
  }
}

better methodパフォーマンスが向上したものはありますか?

4

8 に答える 8

68

サイクルを節約したい場合は、1 つのオブジェクトと 1 つの配列を使用します。

var lookup = {};
var items = json.DATA;
var result = [];

for (var item, i = 0; item = items[i++];) {
  var name = item.name;

  if (!(name in lookup)) {
    lookup[name] = 1;
    result.push(name);
  }
}

このようにして、基本的にindexOf/inArray呼び出しを回避し、オブジェクトのプロパティを反復するよりも速く反復できる配列を取得します。これは、2 番目のケースではhasOwnProperty.

もちろん、オブジェクトだけで問題ない場合は、チェックとresult.pushをまったく回避できます。場合によっては、を使用して配列を取得できますObject.keys(lookup)が、それよりも高速ではありません。

于 2013-07-22T06:18:17.857 に答える
22

Underscore.jsは、この種の作業に最適です。_.countBy()あたりのカウントを取得するために使用できますname

data = [{"id":11,"name":"ajax","subject":"OR","mark":63},
        {"id":12,"name":"javascript","subject":"OR","mark":63},
        {"id":13,"name":"jquery","subject":"OR","mark":63},
        {"id":14,"name":"ajax","subject":"OR","mark":63},
        {"id":15,"name":"jquery","subject":"OR","mark":63},
        {"id":16,"name":"ajax","subject":"OR","mark":63},
        {"id":20,"name":"ajax","subject":"OR","mark":63}]

_.countBy(data, function(data) { return data.name; });

与えます:

{ajax: 4, javascript: 1, jquery: 2} 

キーの配列の場合は、次を使用します_.keys()

_.keys(_.countBy(data, function(data) { return data.name; }));

与えます:

["ajax", "javascript", "jquery"]
于 2014-03-16T00:34:16.647 に答える
6

ここでわかるように、より多くの値がある場合、より良いアプローチがあります。

http://jsfiddle.net/MsYGJ/

temp = {}
// Store each of the elements in an object keyed of of the name field.  If there is a collision (the name already exists) then it is just replaced with the most recent one.
for (var i = 0; i < varjson.DATA.length; i++) {
    temp[varjson.DATA[i].name] = varjson.DATA[i];
}
// Reset the array in varjson
varjson.DATA = [];
// Push each of the values back into the array.
for (var o in temp) {
    varjson.DATA.push(temp[o]);
}

ここではname、 をキーとしてオブジェクトを作成しています。値は、配列の元のオブジェクトです。これを行うと、各置換は O(1) であり、既に存在するかどうかを確認する必要はありません。次に、各値を引き出して、配列を再設定します。


: 配列が小さい場合は、このアプローチの方がわずかに高速です。

注 2
これは元の順序を保持しません。

于 2013-07-22T05:56:34.270 に答える