我的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"}
有没有什么好方法可以从这个JSON中找出distinct name
结果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
给了我更好的表现?
答案 0 :(得分:48)
如果你想保存一些周期,我会使用一个Object和一个Array:
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
。
当然,如果你只使用一个对象,你可以避免检查和result.push
,如果使用Object.keys(lookup)
获取数组,但它不会比这一点。
答案 1 :(得分:15)
使用Jquery方法唯一。
var UniqueNames= $.unique(data.DATA.map(function (d) {return d.name;}));
alert($.unique(names));
答案 2 :(得分:15)
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"]
答案 3 :(得分:8)
这是减少
的好地方var uniqueArray = o.DATA.reduce(function (a, d) {
if (a.indexOf(d.name) === -1) {
a.push(d.name);
}
return a;
}, []);
答案 4 :(得分:6)
正如你在这里看到的,当你有更多的价值时,有更好的方法。
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 :(得分:0)
首先,我们可以运行map()
函数以获取新数组,并在varjson.DATA
中的每个元素上调用提供的函数。
varjson.DATA.map(({name})=>name))
从name
获得varjson.DATA
的数组之后。我们可以将其转换为一个集合,该集合将丢弃数组的所有重复条目,并应用spread operator以获得唯一名称的数组:
[...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))]);
答案 6 :(得分:0)
尝试一下,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;
})
}
答案 7 :(得分:0)
尝试一下:
var distinct_list
= data.DATA.map(function (d) {return d[x];}).filter((v, i, a) => a.indexOf(v) === i)