为了账号安全,请及时绑定邮箱和手机立即绑定

对于两个数组,查找仅存在于一个数组中的项目(对称差异)

对于两个数组,查找仅存在于一个数组中的项目(对称差异)

白板的微信 2023-05-19 17:09:05
我需要比较两个数组并返回一个新数组,其中包含仅在两个给定数组之一中找到的任何项目,但不能同时在两个数组中找到。换句话说,返回两个数组的对称差。我的算法包括在第一个数组上使用 map() 方法,并使用 every() 将该数组的每个元素与第二个数组的元素进行比较。如果此方法返回 true,则该元素将在 map 的块级别返回(最终会将其添加到返回的数组),否则将被丢弃。我不确定为什么我的代码不起作用。这是使用我的代码的错误输出示例:function diffArray(arr1, arr2) {    var newArr = arr1        .map(elem1 => {            if (arr2.every(elem2 => elem2 != elem1)) {                return elem1;            }        });    return newArr;}console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]));这是错误的输出:[ undefined, undefined, undefined, undefined ]预期输出是:[4]
查看完整描述

4 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

您的方法迭代第一个数组,并且由于使用map以及对值的检查,您得到 undefined 的每个元素arr1。


如果您filter也使用另一个数组,您可以获得想要的结果。


function diffArray(arr1, arr2) {

    return [

        ...arr1.filter(elem1 => arr2.every(elem2 => elem2 != elem1)),

        ...arr2.filter(elem1 => arr1.every(elem2 => elem2 != elem1))

    ];

}


console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]));

另一种方法采用两个数组的所有值组成的数组,并通过检查该值是否不包含在两个数组中来进行过滤。


function diffArray(arr1, arr2) {

    return [...arr1, ...arr2].filter(v => arr1.includes(v) !== arr2.includes(v));

}


console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]));


查看完整回答
反对 回复 2023-05-19
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

即使数字在两个数组中多次出现,该算法也能正常工作。


它使用从两个数组的项目创建的 Map。该地图包含该项目作为键,该值是它在第一个数组中找到的次数 - 它在第二个数组中找到的次数。


创建 Map 后,它会转换为 [item, count] 的数组。然后过滤数组,删除所有计数为的项目0(它们在两个数组中均等存在),然后我们将数组映射到项目数组。


const getCounts = (arr, init = new Map(), inc = 1) =>

  arr.reduce((acc, item) => acc.set(item, (acc.get(item) || 0) + inc), init);


function diffArray(arr1, arr2) {

  // create a Map that adds 1 for all items in arr1, and substructs 1 for every item in arr2

  const counts = getCounts(arr2, getCounts(arr1), -1);

  

  // convert to an array of pairs [item, count]

  return Array.from(counts)

    .filter(([, v]) => v) // remove all items with count 0

    .map(([k]) => k); // map to the original item

}


console.log(diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]));

console.log(diffArray([1, 2, 3, 3, 5], [1, 2, 3, 4, 5]));

console.log(diffArray([5, 1, 2, 3, 5], [1, 2, 3, 4, 5, 5]));

console.log(diffArray([1, 1, 2, 2, 3, 3, 5], [1, 2, 2, 3, 4, 5]));


查看完整回答
反对 回复 2023-05-19
?
MMTTMM

TA贡献1869条经验 获得超4个赞

您的函数返回第二个数组中不存在的第一个数组的元素。

.map()它的返回是通过返回与您的输入 ( ) 大小完全相同的数组这一事实来解释的arr1,但是由于所有项目都arr1存在于arr2您不输入if(-statement 正文中,因此undefined被返回。

如果您的目的是返回仅存在于一个数组中的项目(无论它们传入的顺序如何),您可以将该Map对象与Array.prototype.reduce()

  • 将数组参数组合成普通的数组数组

  • 使用 循环遍历这些内部数组.reduce(),构建Map,显示每个项目在组合数组中出现的次数

  • 对于组合数组的每个项目,删除重复项并增加相应的计数器

  • 传播结果Map.entries()那些.filter()找出独特之处

const arr1 = [1, 2, 3, 5], 

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

      

      getUniques = (...arrays) => 

        [...arrays

          .reduce((acc, arr) => {

            [...new Set(arr)]

              .forEach(item => 

                acc.set(item, (acc.get(item)||0)+1))

            return acc

          }, new Map)

          .entries()]

          .reduce((acc, [item, repetitions]) => 

            (repetitions == 1 && acc.push(item), acc), [])

            

console.log(getUniques(arr1, arr2))

.as-console-wrapper {min-height:100%;}

上述方法具有 O(n) 时间复杂度,这与您最初的尝试和您当前接受的答案(均具有 O(n²) 时间复杂度)相反。因此,它可能在大型阵列上执行得更快(任意数量的阵列,作为奖励)。



查看完整回答
反对 回复 2023-05-19
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

使用 _.difference(array, [values])

来自lodash

或者

自己的解决方案:

const diffArray = (arrayA, arrayB) => {

    const output = []

    const setA = new Set(arrayA);

    arrayB.forEach((n) =>{

       if(!setA.has(n)){

         output.push(n)

       }

    })

    const setB = new Set(arrayB);

    arrayA.forEach(n =>{

       if(!setB.has(n)){

         output.push(n)

       }

    })

    return output;

}


console.log(diffArray([1, 2, 3, 5, 6], [1, 2, 3, 4, 5])); //4, 6


查看完整回答
反对 回复 2023-05-19
  • 4 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信