【问题标题】:Quickest way to check if 2 arrays contain same values in javascript检查2个数组是否在javascript中包含相同值的最快方法
【发布时间】:2020-04-22 10:13:23
【问题描述】:

是否有更快或更有效的方法来检查两个数组是否在 javascript 中包含相同的值?

这是我目前正在做的检查。它有效,但很长。

    var arraysAreDifferent = false;
    for (var i = 0; i < array1.length; i++) {
      if (!array2.includes(array1[i])) {
        arraysAreDifferent = true;
      }
    }
    for (var i = 0; i < array2.length; i++) {
      if (!array1.includes(array2[i])) {
        arraysAreDifferent = true;
      }
    }

【问题讨论】:

  • 如果您需要支持旧版 IE 和/或反社会人士,您可以转换为字符串并进行比较:console.log(JSON.stringify(['a','b','c'].sort()) === JSON.stringify(['b','c','a'].sort())); // true
  • @Gavin 感谢 sociopath 评论让我发笑 :) 但是,据我了解,OP 希望 [0,1,1][0,1] 通过测试
  • .sort 的一个问题是计算复杂 - O(n log n),比 O(n) 更糟糕
  • @Gavin 只是一个注释——“或”不是唯一的。事实上,其中任何一个都可能导致另一个。
  • 强烈建议:see georg's answer here 使用集合操作。

标签: javascript arrays compare


【解决方案1】:

要将计算复杂度从 O(n ^ 2) 降低到 O(n),请改用 Set - Set.hasO(1),但 Array.includesO(n)

与常规的 for 循环的冗长手动迭代相比,使用 .every 检查数组中的每个项目是否通过测试。还要检查两个 Set 的大小是否相同 - 如果这样做了,那么如果其中一个数组被迭代,则不需要迭代另一个(除了构造其 Set):

const arr1Set = new Set(array1);
const arr2Set = new Set(array2);
const arraysAreDifferent = (
  arr1Set.size === arr2Set.size &&
  array1.every(item => arr2Set.has(item))

);

【讨论】:

  • 为了纯粹的速度,我们甚至不需要两套。当然,总体复杂度仍然是O(n),但每个集合的创建都是O(n) 本身。因为只有一个是真正需要的,所以只能留下arr2Set,另一个删除。话虽如此,我确实喜欢使用两个集合 - 它使问题更通用,因此可以使用集合代数扩展以涵盖更多内容。
  • 我认为无论如何,这两个数组都必须至少迭代一次,以确保它们的每个元素都包含在另一个元素中,并且为了提高计算复杂性,其中一个需要之后再次迭代。 arr1Set.size === arr2Set.size 有效,但 array1.length === arr2Set.size 无效,因为具有相同值的重复项,或者由于其他数组中未包含的其他项(但其他数组具有重复项)
【解决方案2】:

function same(arr1, arr2){
    //----if you want to check by length as well 
    // if(arr1.length != arr2.length){
    //     return false;
    // }

    // creating an object with key => arr1 value and value => number of time that value repeat;
    let frequencyCounter1 = {};
    let frequencyCounter2 = {};
    for(let val of arr1){
        frequencyCounter1[val] = (frequencyCounter1[val] || 0) + 1;
    }
    for(let val of arr2){
        frequencyCounter2[val] = (frequencyCounter2[val] || 0) + 1;
    }
    for(let key in frequencyCounter1){
        //check if the key is present in arr2 or not 
        if(!(key in frequencyCounter2)) return false;
        //check the number of times the value repetiton is same or not;
        if(frequencyCounter2[key]!==frequencyCounter1[key]) return false;
    }
    return true;
}

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 2019-04-27
    • 2021-08-19
    相关资源
    最近更新 更多