web-dev-qa-db-fra.com

Sélection de valeurs distinctes dans un JSON

J'ai mon JSON comme suit

{"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"}

Existe-t-il une bonne méthode pour connaître le distinct name de ce JSON

Résultat javascript,jquery,ajax

Je peux le faire en utilisant la méthode suivante

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++;
  }
}

Y a-t-il better method ce qui m'a donné de meilleures performances?

25
Nithesh

J'utiliserais un objet et un tableau, si vous voulez enregistrer un cycle:

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);
  }
}

De cette façon, vous évitez essentiellement l'appel indexOf/inArray, et vous obtiendrez un tableau qui peut être itéré plus rapidement que l'itération des propriétés de l'objet - également parce que dans le second cas, vous devez vérifier hasOwnProperty.

Bien sûr, si vous êtes juste avec un objet, vous pouvez éviter la vérification et le result.Push, Et au cas où obtenir le tableau en utilisant Object.keys(lookup), mais ce ne sera pas plus rapide que cette.

51
ZER0

nderscore.js est idéal pour ce genre de chose. Vous pouvez utiliser _.countBy() pour obtenir les nombres par 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; });

Donne:

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

Pour un tableau de clés, utilisez simplement _.keys()

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

Donne:

["ajax", "javascript", "jquery"]
15
Chris Seymour

Utilisez la méthode Jquery unique.

var UniqueNames= $.unique(data.DATA.map(function (d) {return d.name;}));

alert($.unique(names));

JSFiddle

15
Hardik Sondagar

Ceci est un excellent endroit pour réduire

var uniqueArray = o.DATA.reduce(function (a, d) {
       if (a.indexOf(d.name) === -1) {
         a.Push(d.name);
       }
       return a;
    }, []);
8
Evan Borden

Comme vous pouvez le voir ici, lorsque vous avez plus de valeurs, il y a une meilleure approche.

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]);
}

Ici, nous créons un objet avec name comme clé. La valeur est simplement l'objet d'origine du tableau. Pour ce faire, chaque remplacement est O(1) et il n'est pas nécessaire de vérifier s'il existe déjà. Vous extrayez ensuite chacune des valeurs et remplissez à nouveau le tableau.

[~ # ~] note [~ # ~]
Pour les petits tableaux, votre approche est légèrement plus rapide.

NOTE 2
Cela ne préservera pas la commande d'origine.

6
sberry

Tout d'abord, nous pouvons simplement exécuter la fonction map() pour obtenir le nouveau tableau avec les résultats de l'appel d'une fonction fournie sur chaque élément du varjson.DATA.

varjson.DATA.map(({name})=>name))

Après avoir obtenu le tableau de name à partir du varjson.DATA. Nous pouvons le convertir en un ensemble qui supprimera toutes les entrées en double du tableau et appliquera opérateur d'étalement pour obtenir un tableau de noms uniques:

[...new Set(varjson.DATA.map(({name})=>name))]
const varjson = {
  "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"
}

console.log( [...new Set(varjson.DATA.map(({name})=>name))]);
1
hawryschuk