javascript 中的多个数组交集

Multiple array intersection in javascript

如何在 javascript(w/wth JQuery) 中写入以查找数组之间相交的值?

应该是

var a = [1,2,3]
var b = [2,4,5]
var c = [2,3,6]

并且相交函数应该 returns 值为 {2} 的数组。如果可能,它可以适用于任意数量的数组。

谢谢

有很多方法可以实现。

由于您使用的是 jQuery 我建议使用 grep 函数来过滤所有三个数组中存在的值。

var a = [1, 2, 3]
var b = [2, 4, 5]
var c = [2, 3, 6]

var result = $.grep(a, function(value, index) {
  return b.indexOf(value) > -1 && c.indexOf(value) > -1;
})
console.log(result)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

解释:遍历任何数组并过滤掉其他数组中存在的值。

更新(对于多维数组):

概念 - 展平多维数组,即将 [[1,2],3,4] 变换为 [1,2,3,4],然后使用与一维数组相同的逻辑。

示例:

 var a = [
   [1, 4], 2, 3
 ]
 var b = [2, 4, 5]
 var c = [2, 3, 6, [4, 7]]

 //flatten the array's

 //[1,4,2,3]
 var aFlattened = $.map(a, function(n) {
   return n;
 })

 //[2,4,5]
 var bFlattened = $.map(b, function(n) {
   return n;
 })

 //[2,3,6,4,7]
 var cFlattened = $.map(c, function(n) {
   return n;
 })

 var result = $.grep(aFlattened, function(value) {
   return (bFlattened.indexOf(value) > -1 && cFlattened.indexOf(value) > -1);
 });

 console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

// First this is how you declare an array
var a = [1,2,3];
var b = [2,4,5];
var c = [2,3,6];


// Second, this function should handle undetermined number of parameters (so arguments should be used)
function intersect(){
  var args = arguments;
  // if no array is passed then return empty array
  if(args.length == 0) return [];
  
  // for optimisation lets find the smallest array
  var imin = 0;
  for(var i = 1; i < args.length; i++)
    if(args[i].length < args[imin].length) imin = i;
  var smallest = Array.prototype.splice.call(args, imin, 1)[0];
  
  return smallest.reduce(function(a, e){
    for(var i = 0; i < args.length; i++)
      if(args[i].indexOf(e) == -1) return a;
    a.push(e);
    return a;
  }, []);
}

console.log(intersect(a, b, c));

首先 '{}' 表示 JavaScript.
中的对象 这是我的建议。(这是另一种方法)

// declarations  
var a = [1,2,3];  
var b = [2,4,5];  
var c = [2,3,6];  

// filter property of array
a.filter(function(val) {
    if (b.indexOf(val) > -1  && c.indexOf(val) > -1)
        return val;
});

它的作用是检查数组 'a' 中的每个元素并检查该值是否存在于数组 'b' 和数组 'c' 中。如果为真,则 returns 值。简单的!!!。上面的代码应该也适用于 String 但它不适用于 IE < 9,所以要小心。

// Intersecting 2 ordered lists of length n and m is O(n+m)
// This can be sped up by skipping elements
// The stepsize is determined by the ratio of lengths of the lists
// The skipped elements need to be checked after skipping some elements:
// In the case of step size 2 : Check the previous element
// In case step size>2 : Binary search the previously skipped range
// This results in the best case complexity of O(n+n), if n<m
// or the more propable complexity of O(n+n+n*log2(m/n)), if n<m
function binarySearch(array, value, start = 0, end = array.length) {
    var j = start,
        length = end;
    while (j < length) {
        var i = (length + j - 1) >> 1; // move the pointer to
        if (value > array[i])
            j = i + 1;
        else if (value < array[i])
            length = i;
        else
            return i;
    }
    return -1;
}
function intersect2OrderedSets(a, b) {
    var j = 0;
    var k = 0;
    var ratio = ~~(b.length / a.length) - 1 || 1;
    var result = [];
    var index;
    switch (ratio) {
        case 1:
            while (j < a.length) {
                if (a[j] === b[k]) {
                    result.push(a[j]);
                    j++;
                    k++;
                } else if (a[j] < b[k]) {
                    while (a[j] < b[k]) j++;
                } else {
                    while (b[k] < a[j]) k++;
                    if (k >= b.length) break;
                }
            }
            break;
        case 2:
            while (j < a.length) {
                if (a[j] === b[k]) {
                    result.push(a[j]);
                    j++;
                    k++;
                } else if (a[j] < b[k]) {
                    while (a[j] < b[k]) j++;
                } else {
                    while (b[k] < a[j]) k += 2;
                    if (k - 1 >= b.length) break;
                    if (a[j] <= b[k - 1]) k--;
                }
            }
            break;
        default:
            while (j < a.length) {
                if (a[j] === b[k]) {
                    result.push(a[j]);
                    j++;
                    k++;
                } else if (a[j] < b[k]) {
                    while (a[j] < b[k]) j++;
                } else {
                    while (b[k] < a[j]) k += ratio;
                    index = binarySearch(b, a[j], k - ratio + 1, k + 1 < b.length ? k + 1 : b.length - 1);
                    if (index > -1) {
                        result.push(a[j]);
                        j++;
                        k = index + 1;
                    } else {
                        j++;
                        k = k - ratio + 1;
                    }
                    if (k >= b.length) break;
                }
            }
    }
    return result;
}

function intersectOrderedSets() {
    var shortest = 0;
    for (var i = 1; i < arguments.length; i++)
        if (arguments[i].length < arguments[shortest].length) shortest = i;
    var result = arguments[shortest];
    for (var i = 0, a, b, j, k, ratio, index; i < arguments.length; i++) {
        if (result.length === 0) return result;
        if (i === shortest) continue;
        a = result;
        b = arguments[i];
        result = intersect2OrderedSets(a, b);
    }
    return result;
}

使用方法:

intersectOrderedSets(a,b,c);