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

有没有什么好方法可以从这个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让我有更好的表现?

如果你想节省一些周期,我会使用一个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

当然,如果你只使用一个Object就可以了,你可以完全避免检查和result.push ,以防万一使用Object.keys(lookup)获取数组,但它不会比这更快。

使用Jquery方法是唯一的。

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

的jsfiddle

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

正如你在这里看到的,当你有更多的价值时,有更好的方法。

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),并且不需要检查它是否已经存在。 然后,将每个值拉出并重新填充数组。

注意
对于较小的arrays,您的方法稍快一些。

笔记2
这不会保留原始订单。

这是减少的好地方

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