【问题标题】:Check to see if an array contains all elements of another array, including whether duplicates appear twice检查一个数组是否包含另一个数组的所有元素,包括重复是否出现两次
【发布时间】:2022-01-21 03:16:53
【问题描述】:

我需要检查一个数组是否包含另一个数组的所有元素,包括相同的重复项。第二个数组可以有额外的元素。我正在使用每个...包含,但没有发现第二个数组没有正确的重复项。

例如:

const arr1 = [1, 2, 2, 3, 5, 5, 6, 6]
const arr2 = [1, 2, 3, 5, 6, 7]

if(arr1.every(elem => arr2.includes(elem))){
   return true     // should return false because arr2 does not have the same duplicates

}

谢谢!

编辑:arr1 是我正在循环的许多数组之一,这些数组来自图遍历算法,因此我想避免将它们重组为对象以创建字典数据结构。

【问题讨论】:

  • 重复的顺序很重要?
  • 一种方法是对数组进行排序,遍历它们并成对比较元素。如果顺序也很重要,请跳过第一步。
  • @SaeedShamloo 重复的顺序无关紧要
  • @ThomasSablik 我觉得我试过这个但遇到了问题,因为 arr2 可以有额外的元素。我将再次深入研究那个潜在的解决方案!

标签: javascript arrays


【解决方案1】:

您表示在您的 cmets 中顺序无关紧要。这使得这非常简单。

  1. 对两个数组进行排序
  2. 检查对应元素是否相等
    • 考虑与稀疏或短数组相关的错误
  3. 使用.reduce() 将其归结为一个结果

因此,一旦对数组进行排序,这实际上归结为一条语句:

matcher.reduce((acc, value , idx)=>matcher[idx] === test[idx], false);

您还提到了针对许多数组进行测试。所以下面的完整示例是出于演示目的。

let toMatch = [1, 2, 2, 3, 5, 5, 6, 6]
let arrayOfArrays = [[1,2],[1, 2, 3, 5, 6, 7, 3, 9, 8, 2, 7],[1, 2, 3, 3, 6, 7],[1, 3, 3, 5, 6, 7],[1, 2, 3, 5, 6, 6], [3,5,2,1,6,2,5,6]];
let toMatchSorted = toMatch.slice().sort();

arrayOfArrays.forEach(arr=>{
  let toTestSorted = arr.slice().sort();
  let out = toMatchSorted.reduce((acc, value , idx)=>toMatchSorted[idx] === toTestSorted[idx], false);
  console.log(`Input: ${arr}, Result: ${out}`);
});

【讨论】:

    【解决方案2】:

    尝试创建这个函数:

    
     function containsAll (target, toTest) {
    
        const dictionary = {}
    
        target.forEach(element => {
            if (dictionary[element] === undefined) {
                dictionary[element] = 1;
                return;
            }
            dictionary[element]++;
        });
    
    
        toTest.forEach(element => {
            if (dictionary[element] !== undefined)
                dictionary[element]--;
        })
    
        for (let key in dictionary) {
            if (dictionary[key] > 0) return false;
        }
    
        return true;
    
    }
    
    

    然后像这样调用它:

    const arr1 = [1, 2, 2, 3, 5, 5, 6, 6]
    const arr2 = [1, 2, 3, 5, 6, 7]
    
    
    console.log(containsAll(arr1, arr2)) // returns false
    

    【讨论】:

      【解决方案3】:

      这能解决您的问题吗?

      const arr = [1, 2, 3, 5, 6, 7, 2, 10, 2, 3, 2];
      const subArr = [1, 2, 2, 3, 2] 
      const contains = subArr.every(num => subArr.filter(n => n == num).length <= arr.filter(n => n== num).length);
      console.log(contains);

      【讨论】:

        【解决方案4】:
                const arr1 = [1, 2, 2, 3, 5, 5, 6, 6];
                //const arr2 = [1, 2, 3, 5, 6, 7];
                const arr2 = [1, 2, 2, 3, 5, 5];
                let includesAll1 = true;
                let includesAll2 = true;
                const checkObj1 = {
        
                };
        
                const checkObj2 = {
        
                };
        
                arr1.forEach((el)=> {
                    if(checkObj1[el] === undefined) {
                        checkObj1[el] = 1;
                    } else {
                        checkObj1[el]++;
                    }
                });
        
                arr2.forEach((el)=> {
                    if(checkObj2[el] === undefined) {
                        checkObj2[el] = 1;
                    } else {
                        checkObj2[el]++;
                    }
                });
        
                const check1Keys = Object.keys(checkObj1);
                const check2Keys = Object.keys(checkObj2);
        
                if(check1Keys.length > check2Keys.length) {
                    includesAll2 = false;
        
                    check2Keys.forEach((key)=> {
                        const value1 = checkObj1[key];
                        const value2 = checkObj2[key];
        
                        if(!arr1.includes(parseInt(key)) || value1 != value2) {
                            includesAll1 = false;
                        }
                    });
                } else {
                    includesAll1 = false;
        
                    check1Keys.forEach((key)=> {
                        const value1 = checkObj1[key];
                        const value2 = checkObj2[key];
                        console.log(value1, value2, key);
        
                        if(!arr2.includes(parseInt(key)) || value1 != value2) {
                            includesAll2 = false;
                        }
                    });
                }
        
                console.log(includesAll1);
                console.log(includesAll2);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-05
          • 2021-06-04
          • 2016-11-16
          • 2021-12-30
          相关资源
          最近更新 更多