Javascript 检查一个数组中的每个元素是否都在第二个数组中

Javascript 检查一个数组中的每个元素是否都在第二个数组中,javascript,arrays,node.js,Javascript,Arrays,Node.js,我有两个数组,我想检查arr2中的每个元素是否都在arr1中。如果元素的值在arr2中重复,则需要在arr1中重复相同的次数。最好的方法是什么 arr1 = [1, 2, 3, 4] arr2 = [1, 2] checkSuperbag(arr1, arr2) > true //both 1 and 2 are in arr1 arr1 = [1, 2, 3, 4] arr2 = [1, 2, 5] checkSuperbag(arr1, arr2) > false //5

我有两个数组,我想检查
arr2
中的每个元素是否都在
arr1
中。如果元素的值在
arr2
中重复,则需要在
arr1
中重复相同的次数。最好的方法是什么

arr1 = [1, 2, 3, 4]
arr2 = [1, 2]

checkSuperbag(arr1, arr2)
> true //both 1 and 2 are in arr1

arr1 = [1, 2, 3, 4]
arr2 = [1, 2, 5]

checkSuperbag(arr1, arr2)
> false //5 is not in arr1

arr1 = [1, 2, 3]
arr2 = [1, 2, 3, 3]

checkSuperbag(arr1, arr2)
> false //3 is not in arr1 twice

你必须支持蹩脚的浏览器吗?如果没有,该函数应该使这变得容易

如果arr1是arr2的超集,则arr2中的每个成员都必须存在于arr1中

var isSuperset = arr2.every(function(val) { return arr1.indexOf(val) >= 0; });
这里有一个

编辑

所以您定义了超集,使得对于arr2中的每个元素,它在arr1中出现的次数相同?我认为这将有助于您做到这一点(从前面的MDN链接中获取垫片以支持较旧的浏览器):

结束编辑


如果您确实希望支持较旧的浏览器,则上面的MDN链接有一个可以添加的垫片,为了方便起见,我在这里复制该垫片:

if (!Array.prototype.every)  
{  
  Array.prototype.every = function(fun /*, thisp */)  
  {  
    "use strict";  

    if (this == null)  
      throw new TypeError();  

    var t = Object(this);  
    var len = t.length >>> 0;  
    if (typeof fun != "function")  
      throw new TypeError();  

    var thisp = arguments[1];  
    for (var i = 0; i < len; i++)  
    {  
      if (i in t && !fun.call(thisp, t[i], i, t))  
        return false;  
    }  

    return true;  
  };  
}  
if(!Array.prototype.every)
{  
Array.prototype.every=函数(fun/*,thisp*/)
{  
“严格使用”;
if(this==null)
抛出新的TypeError();
var t=对象(本);
var len=t.length>>>0;
如果(乐趣的类型!=“功能”)
抛出新的TypeError();
var thisp=参数[1];
对于(变量i=0;i
编辑


请注意,这将是一个O(N2)算法,因此避免在大型数组上运行它。

一个选项是对两个数组进行排序,然后遍历这两个数组,比较元素。如果在超级包中未找到子包候选中的元素,则前者不是子包。排序通常为O(n*log(n)),比较为O(max(s,t)),其中s和t是数组大小,总时间复杂度为O(m*log(m)),其中m=max(s,t)


如果您希望禁止元素重复,请参见“”以获取一组对象的示例实现。

如果
b
长度超过它不能是超集,则快速解决方案在此处使用两个数组,因此返回false。然后通过
b
循环查看a是否包含该元素。如果是,则将其从
a
中删除,如果不返回false,则继续。更糟糕的情况是,如果
b
是一个子集,则时间将
b.length

function isSuper(a,b){
  var l=b.length,i=0,c;
  if(l>a.length){return false}
  else{
    for(i;i<l;i++){
      c=a.indexOf(b[i]);
      if(c>-1){
        a.splice(c,1);
      }
      else{return false}
    }
    return true;
  }
}
函数发布器(a、b){
var l=b.长度,i=0,c;
如果(l>a.length){return false}
否则{
(i;i-1){
a、 拼接(c,1);
}
else{return false}
}
返回true;
}
}

这假设输入并不总是有序的,如果
a
1,2,3
b
3,2,1
,它仍然会返回true。

还没有人发布递归函数,这些总是很有趣的。像
arr1.containsArray(arr2)
一样调用它

演示:

Array.prototype.containsArray=函数(Array/*,index,last*/){
if(参数[1]){
变量索引=参数[1],最后一个=参数[2];
}否则{
var index=0,last=0;this.sort();array.sort();
};
返回索引==array.length
||(last=this.indexOf(数组[index],last))>-1
&&this.containsArray(数组,++index,++last);
};
使用对象(读取:哈希表)代替排序应将摊销复杂性降低到O(m+n):

功能包包含(arr1、arr2){
var o={}
var结果=真;
//计算容器中的所有对象
对于(变量i=0;i

这将产生
true
false
false
false
,至于另一种方法,您可以如下操作:

函数签入(a、b){
返回b.every(函数(e){
返回e===this.splice(this.indexOf(e),1)[0];
},a.slice());//a.slice()是每个方法中的“this”
}
var arr1=[1,2,3,4],
arr2=[1,2],
arr3=[1,2,3,3];
日志(签入(arr1,arr2));

console.log(签入(arr1,arr3))如果arr2是arr1的子集,则
集合长度(arr1+arr2)=集合长度(arr1)

以下是我的解决方案:

Array.prototype.containsIds = function (arr_ids) {
    var status = true;
    var current_arr = this;
    arr_ids.forEach(function(id) {
        if(!current_arr.includes(parseInt(id))){
            status = false;
            return false; // exit forEach
        }
    });
    return status;
};

// Examples
[1,2,3].containsIds([1]); // true
[1,2,3].containsIds([2,3]); // true
[1,2,3].containsIds([3,4]); // false
在图书馆找到这个。此函数使用内置函数来解决问题
.includes()
.indexOf()
.every()

vararray1=['A','B','C','D','E'];
变量array2=['B','C','E'];
var array3=['B','C','Z'];
var array4=[];
函数ArrayContainesArray(超集、子集){
if(0==子集长度){
返回false;
}
返回子集.every(函数(值){
返回(超集包括(值));
});
}
函数数组内容数组1(超集、子集){
if(0==子集长度){
返回false;
}
返回子集.every(函数(值){
返回值(超集索引(值)>=0);
});
}
log(arrayContainsArray(array1,array2))//真的
log(arrayContainsArray(array1,array3))//假的
log(arrayContainsArray(array1,array4))//假的
log(arrayContainsArray1(array1,array2))//真的
log(arrayContainsArray1(array1,array3))//假的

log(arrayContainsArray1(array1,array4))//false
另一个简单的解决方案如下:

let a = [1,2,'a',3,'b',4,5]

let b = [1,2,4]

console.log(b.every((i) => a.includes(i)))

希望这有帮助

@parapurajkumar-是的,是的。我将在我的答案中添加一个编辑,警告OP关于在大输入时使用此选项Hank Adam我稍微编辑了我的问题,我
function isSuper(a,b){
  var l=b.length,i=0,c;
  if(l>a.length){return false}
  else{
    for(i;i<l;i++){
      c=a.indexOf(b[i]);
      if(c>-1){
        a.splice(c,1);
      }
      else{return false}
    }
    return true;
  }
}
function bagContains(arr1, arr2) {
    var o = {}
    var result = true;

    // Count all the objects in container
    for(var i=0; i < arr1.length; i++) {
        if(!o[arr1[i]]) {
            o[arr1[i]] = 0;
        }
        o[arr1[i]]++;
    }

    // Subtract all the objects in containee
    // And exit early if possible
    for(var i=0; i < arr2.length; i++) {
        if(!o[arr2[i]]) {
            o[arr2[i]] = 0;
        }
        if(--o[arr2[i]] < 0) {
            result = false;
            break;
        }
    }

    return result;
}

console.log(bagContains([1, 2, 3, 4], [1, 3]));
console.log(bagContains([1, 2, 3, 4], [1, 3, 3]));
console.log(bagContains([1, 2, 3, 4], [1, 3, 7]));
var arr1 = [1, 'a', 2, 'b', 3];
var arr2 = [1, 2, 3];

Array.from(new Set(arr1)).length == Array.from(new Set(arr1.concat(arr2))).length
Array.prototype.containsIds = function (arr_ids) {
    var status = true;
    var current_arr = this;
    arr_ids.forEach(function(id) {
        if(!current_arr.includes(parseInt(id))){
            status = false;
            return false; // exit forEach
        }
    });
    return status;
};

// Examples
[1,2,3].containsIds([1]); // true
[1,2,3].containsIds([2,3]); // true
[1,2,3].containsIds([3,4]); // false
let a = [1,2,'a',3,'b',4,5]

let b = [1,2,4]

console.log(b.every((i) => a.includes(i)))