使用组查找所有可能相关值的最佳方法是什么。
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
答案 0 :(得分:5)
简短而精确,没有每次在整个数组中查找条目的开销:
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
的支持。
答案 1 :(得分:3)
<强> SOLUTION:强>
使用grep
,map
和unique
(如果不需要“全部”,则可以删除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
。
<select id="questions">
<option>All</option>
<option>a</option>
<option>b</option>
<option>c</option>
</select>
选择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 <body> later
var $select = $("<select/>", {
"id": "result"
});
//construct an array of <option> tags
var $options = $.map(source, function (r) {
return $("<option/>", {
"html": r
});
});
//append $options to <Select> and then append $select to <body>
$select.append($options).appendTo("body");
});
<强>样本强> http://jsfiddle.net/hungerpain/tSR5P/
关于此解决方案中使用的方法的额外信息
<强> map
强>
json
对象的重塑。 <强> unique
强>
<强> grep
强>
希望这有帮助!
答案 2 :(得分:0)
你可能想要这样的东西:
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;
}
其中groups包含组数据的对象,而容器包含所有唯一值。
答案 3 :(得分:0)
我认为这可行:
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"]
答案 4 :(得分:0)
查看示例here
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));
答案 5 :(得分:0)
很抱歉在这么长时间后提出这个问题,但我找不到解决方法。
我会采用一种更简单(但可能优化程度较低)的ES6方法:
我们从表格开始
const 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" }
];
然后,我们希望所有唯一组值都作为数组,以便我们可以轻松地在选择元素中对其进行循环。
// Get all unique group entries in the table and map them to the value of group
const uniqueGroups = table.filter((entry, index, self) => {
// findIndex will return the index of the first found result
return self.findIndex(a => a.group === entry.group) === index;
).map(entry => entry.group);
为了争辩,想象有人点击了一个小组。
// Image someone clicked on the group "c"
const chosenGroup = uniqueGroups[2]; // This would be the event handler value of the chosen option
然后,我们过滤掉表中与该组值相对应的所有条目,并将实体映射到填充值。
// Get all stuff related to chosen group
const stuff = table.filter(entry => entry.group === chosenGroup).map(entry => entry.stuff);
我认为这样做更容易,对于少量数据完全没问题。