jQuery 从 JSON 中选择不同的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17780508/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Selecting distinct values from a JSON
提问by Nithesh Narayanan
I have my JSON as follows
我有我的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"}
Is there any good method to find out the distinct name
from this JSON
有什么好的方法可以distinct name
从这个 JSON 中找出
Result javascript,jquery,ajax
结果 javascript,jquery,ajax
I can do this using following methode
我可以使用以下方法来做到这一点
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++;
}
}
Is there any better method
which gave me better performance?
有没有better method
给我更好的表现?
回答by ZER0
I would use one Object and one Array, if you want to save some cycle:
如果你想节省一些循环,我会使用一个对象和一个数组:
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);
}
}
In this way you're basically avoiding the indexOf
/ inArray
call, and you will get an Array that can be iterate quicker than iterating object's properties – also because in the second case you need to check hasOwnProperty
.
通过这种方式,您基本上避免了indexOf
/inArray
调用,并且您将获得一个 Array ,它可以比迭代对象的属性更快地迭代 – 也是因为在第二种情况下您需要检查hasOwnProperty
.
Of course if you're fine with just an Object you can avoid the check and the result.push
at all, and in case get the array using Object.keys(lookup)
, but it won't be faster than that.
当然,如果您只使用 Object 就可以了,您可以完全避免检查和result.push
,并且万一使用 获取数组Object.keys(lookup)
,但它不会比这更快。
回答by Chris Seymour
Underscore.jsis great for this kind of thing. You can use _.countBy()
to get the counts per name
:
Underscore.js非常适合这种事情。您可以使用_.countBy()
来获取 per 的计数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; });
Gives:
给出:
{ajax: 4, javascript: 1, jquery: 2}
For an array of the keys just use _.keys()
对于一组键,只需使用 _.keys()
_.keys(_.countBy(data, function(data) { return data.name; }));
Gives:
给出:
["ajax", "javascript", "jquery"]
回答by Hardik Sondagar
回答by Evan Borden
This is a great spot for a reduce
这是一个减少的好地方
var uniqueArray = o.DATA.reduce(function (a, d) {
if (a.indexOf(d.name) === -1) {
a.push(d.name);
}
return a;
}, []);
回答by sberry
As you can see here, when you have more values there is a better approach.
正如您在此处看到的,当您拥有更多值时,就会有更好的方法。
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]);
}
Here we are creating an object with the name
as the key. The value is simply the original object from the array. Doing this, each replacement is O(1) and there is no need to check if it already exists. You then pull each of the values out and repopulate the array.
在这里,我们正在创建一个以name
为键的对象。该值只是数组中的原始对象。这样做,每次替换都是 O(1) 并且不需要检查它是否已经存在。然后将每个值拉出并重新填充数组。
NOTE
For smaller arrays, your approach is slightly faster.
注意
对于较小的阵列,您的方法稍微快一些。
NOTE 2
This will not preserve the original order.
注 2:
这不会保留原始顺序。
回答by hawryschuk
First we can just run map()
function to get the new array with the results of calling a provided function on every element in the varjson.DATA
.
首先,我们可以运行map()
function 来获取新数组,结果是在varjson.DATA
.
varjson.DATA.map(({name})=>name))
After getting the array of name
from the varjson.DATA
. We can convert it into a set that will discard all duplicate entries of array and apply spread operatorto get a array of unique names:
得到的阵列后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))]);
回答by Shailesh Tiwari
try this, MYJSON will be your json data.
试试这个,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;
})
}