“过滤”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.keys
和Array.prototype.forEach
的支持。
解:
使用grep
, map
和unique
(如果不需要“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; }
情景 :
我们有这些选项的下拉菜单 – a
, b
, c
, All
。
选择一个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
- 文档: http : //api.jquery.com/jQuery.map/
- 作用:将数组或对象中的所有项目转换为新的项目数组。 有点像你的
json
对象的重新json
。
unique
- 文档: http : //api.jquery.com/jQuery.unique/
- 它的作用:从数组中删除重复项。
grep
- 文档: http : //api.jquery.com/jQuery.grep/
- 查找满足过滤函数的数组元素。
希望这可以帮助!
我认为这可行:
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; }
其中,组包含组数据的对象,而容器包含所有唯一值。