【问题标题】:How to get the difference between two arrays?如何获得两个数组之间的差异?
【发布时间】:2017-01-01 10:10:40
【问题描述】:

我有 2 个数组:

arr1 = [[11,12],[11,13],[11,14], [12,13]];
arr2 = [[11,13],[11,14]];

预期结果[[11,12],[12,13]]

我怎样才能得到两个数组之间的差异?我使用 lodash _.difference 但它给了我一个错误的答案。

【问题讨论】:

标签: javascript arrays lodash array-difference


【解决方案1】:

你需要使用_.differenceWith(),因为你需要比较子数组的元素。默认情况下,它只是测试子数组是否是相同的对象,而它们可能不是。

result = _.differenceWith(arr1, arr2, _.isEqual);

【讨论】:

    【解决方案2】:

    仅使用 javascript,并且仅用于此示例和类似示例

    var a1 = [[11,12],[11,13],[11,14], [12,13]];
    var a2 = [[11,13],[14,11]];
    var a3 = a1.filter(ar1 => !a2.some(ar2 => ar1.every(n1 => ar2.includes(n1))))
    console.log(a3); // [[11,12],[12,13]]
    

    创建通用解决方案的标准太多。

    例如是[11,12]和[12,11]一样,可能只是对同一个数组的引用是一样的,(ar1 === ar2)true一样。如果同一个数组中有两个相同的条目,另一个中有一个,你是过滤掉一个,还是保留它?问题的数量可能会持续一段时间,并且嵌套越深,数组中存储的类型数量越多,情况就会变得更糟。

    var a1 = [[11,12],[11,13],[11,14], [12,13]]
    var a2 = [[11,13],[14,11],[12,14]];
    a3 = [];
    [[a1,a2],[a2,a1]].forEach(a=>{
        a3.push(...a[0].filter(
            ar1 => !a[1].some(
                ar2 => ar1.every(
                    n1 => ar2.includes(n1)
                )
            )
        ))
    });
    console.log("[["+a3.join("], [")+"]]")

    【讨论】:

    • 这只会检查a1 而不是a2。对于var a1 = [[11,12],[11,13],[11,14], [12,13]]; var a2 = [[11,13],[14,11],[12,14]]; 的情况,它将失败
    • @redu 关键不是,没有关于什么构成相等和不等的详细规则集……您只能构建特定的测试用例。如果没有包含作为参数的附加信息,则没有适用于所有情况的此问题的解决方案。需要多少?
    【解决方案3】:

    只需几行纯 JS 就足以完成这个分离(并集)工作。此外,您应该确保检查两个数组。

    var arr1 = [[11,12],[11,13],[11,14],[12,13]],
        arr2 = [[11,13],[11,14],[12,14]];
         res = arr1.reduceRight((p,c,i,a) => { var fi = p.findIndex(s => c.every(n => s.includes(n)));
                                               return fi !== -1 ? (a.splice(i,1),
                                                                   p.splice(fi,1),
                                                                   p)
                                                                :  p;
                                             },arr2)
                   .concat(arr1);
    console.log(res);

    【讨论】:

      【解决方案4】:

      你可以在没有 lodash 的情况下做到这一点。提示是将子数组映射为字符串以便于比较

      var arr1 = [[11,12],[11,13],[11,14], [12,13]];
      var arr2 = [[11,13],[11,14],[12,14]];
      
      var res = arr1.concat(arr2).map(x => x.join(",")).filter((x,i,arr) => arr.indexOf(x) === arr.lastIndexOf(x)).map(x => x.split(","));
      
      console.log(res);

      【讨论】:

      • 这只会检查 a1 而不是 a2。对于var a1 = [[11,12],[11,13],[11,14], [12,13]]; var a2 = [[11,13],[14,11],[12,14]]; 的情况,它将失败
      • @Redu 我刚刚修复了这个错误
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2021-12-28
      • 2018-05-19
      相关资源
      最近更新 更多