4

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

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
4

6 回答 6

6

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

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当然。

于 2013-06-25T14:00:55.960 回答
3

解决方案:

使用grep, mapand (如果不需要“全部” 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>

选择an 时option,您希望从中获取相关输出getOption()并将其显示为 another 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

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

unique

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

grep

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

希望这可以帮助!

于 2013-06-25T17:06:40.390 回答
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 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));
于 2013-06-25T13:59:15.217 回答
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"]
于 2013-06-25T13:47:08.893 回答
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 包含组数据的对象,而 container 包含所有唯一值。

于 2013-06-25T13:45:08.560 回答
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

然后我们过滤掉表中与该组值对应的所有条目,并将这些条目映射到 stuff 值。

// Get all stuff related to chosen group
const stuff = table.filter(entry => entry.group === chosenGroup).map(entry => entry.stuff);

我认为这对于少量数据来说更容易并且完全没问题。

于 2020-07-21T14:04:24.977 回答