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

如果您想节省一些循环,我会使用一个对象和一个数组:

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 就可以了,您可以完全避免检查和 the 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 回答
17

使用独特的 Jquery 方法。

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

alert($.unique(names));

JSFiddle

于 2013-07-22T06:27:12.537 回答
12

这是减少的好地方

var uniqueArray = o.DATA.reduce(function (a, d) {
       if (a.indexOf(d.name) === -1) {
         a.push(d.name);
       }
       return a;
    }, []);
于 2013-07-22T06:26:36.527 回答
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 回答
4

首先,我们可以运行map()函数来获取新数组,并在varjson.DATA.

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

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

于 2019-04-04T17:08:55.583 回答
2

试试这个,MYJSON 将是你的 json 数据。

var mytky=[];
mytky=DistinctRecords(MYJSON,"mykeyname");

function DistinctRecords(MYJSON,prop) {
  return MYJSON.filter((obj, pos, arr) => {
    return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
 })
}
于 2019-09-23T20:14:58.253 回答
0

试一试:

var distinct_list 

  = data.DATA.map(function (d) {return d[x];}).filter((v, i, a) => a.indexOf(v) === i)
于 2020-09-09T12:44:16.073 回答