“过滤”JSON获取唯一键并获取所有相关值

什么是找到组中所有可能相关值的最佳方法。

var table = [ {group:"a", stuff:"new"}, {group:"a", stuff:"old"}, {group:"b", stuff:"newOld"}, {group:"b", stuff:"old"}, {group:"c", stuff:"new"}, {group:"c", stuff:"old"}, {group:"c", stuff:"newOld"}, ]; 

我想填充一个包含唯一group值的下拉列表。 在选择时我想使用所有相关的stuff进行进一步处理。 并且还想添加一个包含所有stuff的组。 例如

 on selection of all -> new, old, newOld a -> new, old b -> newOld, old c -> new, old, newOld 

简短而精确,无需每次在整个数组中查找条目的开销:

 var groups = {all:{}}; table.forEach(function(a){ if (!groups[a.group]){ groups[a.group] = {}; } groups[a.group][a.stuff] = groups["all"][a.stuff] = 1; }); 

列出对象中的内容,因此您没有重复的条目(这就是为什么相当冗余=1 )。 但您可以轻松扩展它以计算重复项:

 table.forEach(function(a){ if (!groups[a.group]){ groups[a.group] = {}; } var stuff = groups["all"][a.stuff]; groups["all"][a.stuff] = !stuff ? 1 : ++stuff; stuff = groups[a.group][a.stuff]; groups[a.group][a.stuff] = !stuff ? 1 : ++stuff; }); 

结果如下所示:

 // "groups" holds all group elements and their stuff values groups = { "all": {"new":2,"old":3,"newOld":2}, "a" : {"new":1,"old":1}, "b" : {"newOld":1,"old":1}, "c" : {"new":1,"old":1,"newOld":1} } 

要检索组的值,只需说:

 var groupname = "a"; // whatever group you need Object.keys(groups[groupname]); // will give you: ["new","old"] 

演示

当然要注意Object.keysArray.prototype.forEach的支持。

解:

使用grepmapunique (如果不需要“All”,则可以删除unique的用法)。 这是代码:

 function getOptions(value) { //check if value sent in is an option or "All" options var isAll = value === "All" ? true : false; var forVal; //If its "All" options if (isAll) { //yes, "All" has been chosen. yay! //retreive all the values in "stuff" keys in array var internal = $.map(table, function (r) { return r["stuff"]; }) console.log(internal); //get the unique values in internal[] forVal = $.unique(internal); //or use grep instead if u like to use unique with only DOM elements } else { //use grep to filter out the other options except the chosen option var internal = $.grep(table, function (row) { return row["group"] === value; }); //rip out the the values in "stuff" keys in internal[] forVal = $.map(internal, function (r) { return r["stuff"] }); } //return the output variable return forVal; } 

情景

我们有这些选项的下拉菜单 – abcAll

  

选择一个option ,您希望从getOption()获取相关输出并将其显示为另一个select

 $("select").change(function () { //remove all #result select boxes - litter of previous option selection $("#result").remove(); //get the options from the getOptions function var source = getOptions(this.value); //declare a select tag - will be inserted into  later var $select = $("", { "id": "result" }); //construct an array of ", { "html": r }); }); //append $options to  

演示 http://jsfiddle.net/hungerpain/tSR5P/

关于在这个解决方案中使用的方法的额外信息

map

  1. 文档: http : //api.jquery.com/jQuery.map/
  2. 作用:将数组或对象中的所有项目转换为新的项目数组。 有点像你的json对象的重新json

unique

  1. 文档: http : //api.jquery.com/jQuery.unique/
  2. 它的作用:从数组中删除重复项。

grep

  1. 文档: http : //api.jquery.com/jQuery.grep/
  2. 查找满足过滤函数的数组元素。

希望这可以帮助!

我认为这可行:

 var table = [ {group:"a", stuff:"new"}, {group:"a", stuff:"old"}, {group:"b", stuff:"newOld"}, {group:"b", stuff:"old"}, {group:"c", stuff:"new"}, {group:"c", stuff:"old"}, {group:"c", stuff:"newOld"} ]; var groups = {}; var all = []; for(var i = 0; i < table.length; i++) { var group = table[i]; if(typeof groups[group.group] === "undefined") { groups[group.group] = []; } if (all.indexOf(group.stuff) == -1){ all.push(group.stuff); } groups[group.group].push( group.stuff ); } all.sort(); 

因此变量all包含每个可能的值, groups包含每个组的值:

 console.log(groups.a) > ["new", "old"] console.log(groups.b) > ["newOld", "old"] console.log(groups.c) > ["new", "old", "newOld"] 

看这里的样本

 var table = [ {group:"a", stuff:"new"}, {group:"a", stuff:"old"}, {group:"b", stuff:"newOld"}, {group:"b", stuff:"old"}, {group:"c", stuff:"new"}, {group:"c", stuff:"old"}, {group:"c", stuff:"newOld"}, ]; var filter = function(selected) { var newArr = []; $.each(table, function(idx, item){ if((selected == null || selected == item.group) && $.inArray(item.stuff, newArr) == -1) { newArr.push(item.stuff); } }); return newArr; }; // using console.log(filter('a')); // for selecting 'all' console.log(filter(null)); 

你可能想要这样的东西:

 var groups = {}, container = [], tracker = {}; for (var i = 0, l = table.length; i < l; i++) { var group = table[i].group, stuff = table[i].stuff; if (!groups.hasOwnProperty(group)) groups[group] = []; groups[group].push(stuff); if (tracker.hasOwnProperty(stuff)) continue; container.push(stuff); tracker[group] = undefined; } 

其中,组包含组数据的对象,而容器包含所有唯一值。