jQuery数组交集

5
我之前将这个问题发布在jquery/javascript: arrays - jquery/javascript: arrays。但由于我是一个完全的初学者,所以我错误地表达了问题,也没有理解答案... :(
在无法实现给定的解决方案后,我进行了更多的搜索,发现我需要比较6个可能选择的数组,并将它们相交,最终仅显示重叠值。
因此,这是一个更清晰的表述:
我有6个问题/6组单选按钮的答案。每个答案都有多个值(可以从1到38个项目),以在最终“建议”中显示。我正在收集选中单选按钮的值并将其存储在数组中。我得到6个数组。
如何相交6个数组,以获取仅包含所有6个选择的相交值的最终数组? 如何将此最终数组的项目转换为选择器?
请问有人能帮帮我吗? 谢谢!
我的脚本现在看起来像:
(function($){
  $.fn.checkboxval = function(){
      var outArr = [];
      this.filter(':checked').each(function(){
            outArr.push(this.getAttribute("value"));
      });
      return outArr;
  };
})
(jQuery);
$(function(){
  $('#link').click(function(){
    var valArr1 = $('#vraag1 input:radio:checked').checkboxval();
    var valArr2 = $('#vraag2 input:radio:checked').checkboxval();
    var valArr3 = $('#vraag3 input:radio:checked').checkboxval();
    var valArr4 = $('#vraag4 input:radio:checked').checkboxval();
    var valArr5 = $('#vraag5 input:radio:checked').checkboxval();
    var valArr6 = $('#vraag6 input:radio:checked').checkboxval();
// var newArray = $.merge(valArr1, valArr2, valArr3, valArr4, valArr5, valArr6); <- test to see if I can merge them
// $('#output').text(newArray.join(',')); <- test to see if I can join them
//$("#output").html($("#output").html().replace(/,/gi, ',#diet')); <- test to see if I can append text so it looks like the selectors of divs I need to display later
//    return false;
  });
});

我的表单/输入框看起来像这样:

<input name="vraag1" type="radio" value="1a,4,5,12,13,17a,18,19,22,23,24,26,27,28,29,30,33,38,6" class="radio advice" id="vraag1-0" /><label for="vraag1-0">ja</label>
<br />
<input name="vraag1" type="radio" value="1b,1,2,3,7,8,11,9,14,15,16,17,20,21,25,31,34,35,36,37,10,32" class="radio advice" id="vraag1-1" /><label for="vraag1-1">nee</label>
<br />
<input name="vraag1" type="radio" value="1c,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17a,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38" class="radio advice" id="vraag1-2" /><label for="vraag1-2">maakt mij niet uit</label>

这不应该是$('#vraagX input:radio:checked').val();而不是checkboxval()吗? - mplungjan
@mplungjan:当我将var valArr1 = $('#vraag1 input:radio:checked').checkboxval();更改为var valArr1 = $('#vraag1 input:radio:checked').val();时,它不返回任何值。 - tschardak
抱歉,我在评论中是否提到了函数checkboxval?如果是的话那是我的错。不过它进行了过滤并且调用了它,所以至少这方面是没有浪费的。 - mplungjan
没事了。是的,我同意你的观点,但是由于缺乏更好的知识,我把它们组合在一起了。请问如何求6个数组的交集?谢谢。 - tschardak
6个回答

17

在加载了jQuery之后,你可以在控制台中输入以下内容:

a1=[1,2,3]
a2=[2,3,4,5]
$.map(a1,function(a){return $.inArray(a, a2) < 0 ? null : a;})

输出应该是:

[2, 3]

12

我也在想同样的问题,并得出了以下答案:

$(["a","b"]).filter(["a","c"])

返回

["a"]

太棒了!这是 .filter 的预期应用吗? - David John Smith
1
@david-john-smith 上面的符号没有记录,但是有记录的是.filter接受另一个jQuery对象作为参数。因此,$(["a","b"]).filter($(["a","c"]))是完全合法的。 - Christoph
1
@Christoph提到的文档:http://api.jquery.com/filter/#filter-selection - allicarn

1
如果您想在数组上执行交集操作,可以使用jQuery插件jQuery Array Utilities
以下是如何使用它的示例代码行:
$.intersect([1, 2, 2, 3], [2, 3, 4, 5, 5])

将返回结果[2,3]。

它的表现很棒,但你犯了一个拼写错误:应该是intersect,而不是instersect。 - jobima
谢谢您的评论 :) 我已经对答案进行了更正。 - Kristian Abrahamsen
这个交集函数还支持任意数量的数组,这个包 jquery-array-utilities 也可以使用 bower 安装。我想添加一个免责声明,我最初制作了这个插件 :) - Kristian Abrahamsen

0
你的问题对我来说仍然很困惑。
但是看起来你正在从输入中获取值并尝试将它们组合在一起。但它们都是字符串而不是数组。
尝试将这些字符串只是添加在一起,然后使用 split() (demo)进行分割。
$('#link').click(function() {
    var radios = '';
    $('input:radio:checked').each(function() {
        radios += $(this).val() + ',';
    })
    // remove last comma & convert to array
    radios = radios.substring(0, radios.length - 1).split(',');
    // do something with the array
    console.debug(radios);
})

更新:好的,从您的演示HTML中,我无法得到6个重复项,因此在演示中我将其设置为查找3个以上的匹配项。我不得不编写这个脚本来查找数组中的重复项,我还使它返回具有重复次数的关联对象。可能有更好的方法,但这就是我想出来的(更新演示):
$(function() {
    $('#link').click(function() {
        var radios = '';
        $('input:radio:checked').each(function() {
            radios += $(this).val() + ',';
        })
        // remove last comma & convert to array
        var results = [],
            dupes = radios
             .substring(0, radios.length - 1)
             .split(',')
             .getDuplicates(),
            arr = dupes[0],
            arrobj = dupes[1],
            minimumDuplicates = 6; // Change this to set minimum # of dupes to find

        // find duplicates with the minimum # required
        for (var i=0; i < arr.length; i++){
            if ( arrobj[arr[i]] >= minimumDuplicates ){
                results.push(arr[i]);
            }
        }

        // Show id of results
        var diets = $.map(results, function(n,i){ return '#diet' + n; }).join(',');
        $(diets).show(); // you can also slideDown() or fadeIn() here
    })
});


/* Find & return only duplicates from an Array
 * also returned is an object with the # of duplicates found
 * myArray = ["ccc", "aaa", "bbb", "aaa", "aaa", "aaa", "aaa", "bbb"];
 * x = myArray.getDuplicates();
 * // x = [ array of duplicates, associative object with # found]
 * // x = [ ['aaa','bbb'] , { 'aaa' : 5, 'bbb' : 2 } ]
 * alert(x[0]) // x[0] = ['aaa','bbb'] & alerts aaa,bbb
 * alert(x[1]['aaa']) // alerts 5;
 */
Array.prototype.getDuplicates = function(sort) {
    var u = {}, a = [], b = {}, c, i, l = this.length;
    for (i = 0; i < l; ++i) {
        c = this[i];
        if (c in u) {
            if (c in b) { b[c] += 1; } else { a.push(c); b[c] = 2; }
        }
        u[c] = 1;
    }
    // return array and associative array with # found
    return (sort) ? [a.sort(), b] : [a, b];
}

你看过演示吗?另外,当你说重叠时,是指所有6个组都需要有相同的数量吗?这就让人感到困惑了,因为你的示例HTML(其他问题)只有一个输入值,而上面的代码有很多个。 - Mottie
不同,这是后来添加的独特项目,但它需要在正确的顺序中。 - tschardak
哎呀..好吧,如果我更改默认选项,那么您可能会得到6个以上的重复项。 - Mottie
它似乎有效(http://jsfiddle.net/zDySw/5/)...我将您列出的选中组合设置为默认值,结果得到“30”。 - Mottie
真的!:-)) 这太棒了。非常感谢。有没有办法将返回的结果转换为id选择器,最终显示相应的div?在上面的第一个实例中,我使用了:$("#output").html($("#output").html().replace(/,/gi, ',#diet'));将",#diet"附加到它们上面,以便它们看起来更像我需要显示的div的选择器... - tschardak
显示剩余15条评论

0

-1
function intersect(a, b) {
    var aIsShorter = a.length < b.length;
    var shorter = aIsShorter ? a : b;
    var longer = aIsShorter ? b : a;

    return longer.filter(isFoundInOther).filter(isFoundOnce);

    function isFoundInOther(e) {
        return shorter.indexOf(e) !== -1;
    }

    function isFoundOnce(element, index, array) {
        return array.indexOf(element) === index;
    }
}

介意为您的代码添加说明以及它如何回答 OP 的问题吗? - António Ribeiro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接