检查一个数组是否包含另一个数组的所有元素,包括重复出现的元素是否出现两次。

3
我需要检查一个数组是否包含另一个数组的所有元素,包括相同的重复元素。第二个数组可能有额外的元素。我正在使用every...includes,但它没有捕捉到第二个数组没有正确的重复项。
例如:
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是我遍历的许多数组之一,这些数组是从图遍历算法中获得的,因此如果可能的话,我想避免将它们重构为对象以创建字典数据结构。


重复项的顺序是否重要? - Saeed Shamloo
一种方法是对数组进行排序,迭代它们并逐个比较元素。如果顺序也很重要,只需跳过第一步即可。 - Thomas Sablik
@SaeedShamloo 重复项的顺序无关紧要。 - Robyn
@ThomasSablik 我感觉我尝试过这个,但因为arr2可能有额外的元素而遇到了问题。我会再次深入研究这个潜在的解决方案! - Robyn
4个回答

0
        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);

0
请尝试创建这个函数:

 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

0

这个解决了你的问题吗?

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);


0

你在评论中提到顺序不重要,这使得问题变得非常简单。

  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}`);
});


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