从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"]
正如你在这里看到的,当你有更多的价值时,有更好的方法。
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; }, []);