【问题标题】:jQuery / javascript find values within a listjQuery / javascript 在列表中查找值
【发布时间】:2010-12-01 19:36:15
【问题描述】:

我正在处理一个特殊的问题。我会开始含糊不清,如果有人需要更多详细信息,我可以提供该项目的背景。

我有一个选定的 ID(从复选框中选择):161

我有很多这样的 ID 行:

["161", "165", "573", "190", "150", "283"] // this one would be it
["160", "311", "793", "309", "301"]
["161", "165", "395", "306"] // this one would be it
["160", "311", "668", "191", "216", "301"]

我需要从上面的 ID 行中识别出哪些具有已选择的 ID。这并不难,我可以遍历每一行 ID(遍历实际数组)并执行thisIDList[i] == selectedID

我遇到的问题是选择了多个 ID:["161", "306"]

现在我需要遍历行并确定哪些行具有 both 的选定 ID。

["161", "165", "573", "190", "150", "283"] // wouldn't be it
["160", "311", "793", "309", "301"]
["161", "165", "395", "306"] // this one would be it
["160", "311", "668", "191", "216", "301"]

等等。可以选择 1 到 5 或 6 个 ID:["161", "306", "216", "668"]

有人能指出我正确的方向吗?我认为这基本上就像比较两个列表,其中列表 A 中的每个项目都需要在列表 B 中找到。


编辑

我应该补充一点,该行可以包含在所选列表中找不到的其他 ID。所以如果选择的 ID 是 ["161", "306"],那么 ["161", "165", "395", "306"] 仍然是匹配的,即使它包含 165 和 395。


编辑

将更新并提供更多信息。我有一个单选按钮列表:

<input type="checkbox" name="filter" value="301" />
<input type="checkbox" name="filter" value="161" />
<input type="checkbox" name="filter" value="573" />
<input type="checkbox" name="filter" value="190" />

我有一个无序列表,每个列表都有一个数据属性(我正在使用元数据插件):

<ul>
    <li data="{attrID: '160,197,161,194,195,190,162' }">Lorem Ipsum</li>
</ul>

单击单选按钮时:

// set the selected IDs
selectedIds = []; 
$("input[name=filter]:checked").each(function(){ 
     selectedIds.push(this.value);
});

// loop through each list                   
$('ul li').each(function () {  

    // get and set the metadata for the attrID key
    meta = $(this).metadata();
    idList = meta.attrID;   

    // find out if the selected IDs are found in this idList
    var isMatch = matches(selectedIds,idList);

    console.log(isMatch);

    // my plan was to do this
    if(isMatch){
        // do something with this list item
    }


});

【问题讨论】:

    标签: javascript jquery arrays list


    【解决方案1】:

    这使用了来自 jQuery 的 inArray 函数。它返回一个数组,其中包含集合的索引,该集合包含目标集合的所有元素。如果您的集合相对较小,例如您的示例,它应该足够快。

    function matches( target, sets )
    {
        var matches= [];
        for (var i = 0, setsLen = sets.length; i < setsLen; ++i ) {
            if (isSubset(target,sets[i])) {
               matches.push(i);
            }
        }
        return matches;
    }
    
    function isSubset( target, set )
    {
        for (var j = 0, targetLen = target.length; j < targetLen; ++j) {
             if ($.inArray(target[j], set) < 0) {
                 return false;
             }
        }
        return true;
    }
    

    基于您的数据的小测试脚本:

    $(function(){
        var sets = [
                      ["161", "165", "573", "190", "150", "283"],
                      ["160", "311", "793", "309", "301"],
                      ["161", "165", "395", "306"],
                      ["160", "311", "668", "191", "216", "301"]
        ];
    
        alert( matches( [ "161" ], sets ) );
        alert( matches( [ "161","306" ], sets ) );
     });
    

    编辑:我根据您的补充更新了我的示例。我认为您只需要使用 isSubset 函数。我会把剩下的答案留给上下文。

    【讨论】:

    • 谢谢!实现这一点的最佳方法是什么?目前我正在做var isMatch = matches(selectedIds,idList);,然后将其输出到控制台。它返回 [0] 我猜这意味着不匹配。它还返回 [0, 1] 或 [0, 1, 2] 这很奇怪,因为只有一个匹配项。
    • 我会谨慎使用与函数中的变量相同的名称
    • 这是我从萤火虫那里得到的原始输出。 pastebin.com/raw.php?i=9py2Yn2v
    • @jyoseph -- 错字,内循环中的索引是j,而不是i。我已经修好了。
    • @Eric - 很公平,但我已经将变量的范围限定为函数本地,因此不应该有任何冲突。
    【解决方案2】:

    最快和最可重用的方法是创建一个 isSubset 函数。你甚至都不依赖 jQuery!

    function isSubset(largeSet, smallSet){
    
        for(var i=0; i<smallSet.length; i++){
            if(largeSet.indexOf(smallSet[i]) == -1){
                //not found.
                return false;
            }
        }
    
        return true;
    }
    

    现在遍历所有 ID 列表数组并传入您选择的 ID 数组:

    isSubset(idList, selectedIds);
    

    如果以上返回 true,则您已经确定了一个有效的列表!

    =============

    编辑:感谢 Eric 指出 indexOf() 的漏洞。

    以下代码应该可以解决所有浏览器上的该问题:

    if (!Array.indexOf) {
      Array.prototype.indexOf = function (obj, start) {
        for (var i = (start || 0); i < this.length; i++) {
          if (this[i] == obj) {
            return i;
          }
        }
        return -1;
      }
    }
    

    【讨论】:

    【解决方案3】:

    如果您从对每个数组进行排序开始,则只需遍历每个列表一次。

    【讨论】:

      【解决方案4】:

      当找到一个 X id 时增加一个变量,并在它到达末尾时将它与全部选定的 Id 匹配如何。如果已找到 4 个中的 4 个,则存在匹配项

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        • 2012-12-02
        • 1970-01-01
        相关资源
        最近更新 更多