Подтвердить что ты не робот

Выбор отдельных значений из JSON

У меня есть мой 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, который дал мне лучшую производительность?

4b9b3361

Ответ 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, и вы получите массив, который может быть повторен быстрее, чем итерационные свойства объекта, также потому, что во втором случае вам нужно проверить hasOwnProperty.

Конечно, если у вас все в порядке с Object, вы можете вообще избежать проверки и result.push, и в случае получения массива с помощью Object.keys(lookup), но это не будет быстрее.

Ответ 2

Использовать уникальный метод JQuery.

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

alert($.unique(names));

JSFiddle

Ответ 3

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"]

Ответ 4

Как вы можете видеть здесь, когда у вас больше значений, есть лучший подход.

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
Это не сохранит первоначальный порядок.

Ответ 5

Это отличное место для уменьшения

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

Ответ 6

Сначала мы можем просто запустить функцию map() чтобы получить новый массив с результатами вызова предоставленной функции для каждого элемента в varjson.DATA.

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

После получения массива name из varjson.DATA. Мы можем преобразовать его в набор, который отбросит все повторяющиеся записи массива и применяет оператор распространения, чтобы получить массив уникальных имен:

[...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))]);