【问题标题】:How to compare an array of strings in Javascript?如何比较Javascript中的字符串数组?
【发布时间】:2016-01-22 07:25:23
【问题描述】:

我想看看两个字符串数组是否相等。

例如:

compare(["abc", "def"], ["def", "abc"])

应该返回 true 并且类似地,

compare(["abc", "def"], ["def", "ghi"]) 

应该返回false

最好的方法是什么?

【问题讨论】:

  • 请提供您尝试此操作的代码
  • 要么对数组进行排序并将 a[n] 与 b[n] 进行比较,要么跳过排序并在 b 的每个位置查找 a[n]。

标签: javascript arrays compare string-comparison


【解决方案1】:

JavaScript 没有 Set 或 Multiset 数据结构(至少,没有广泛的浏览器支持),这是您通常用于测试两组项目是否相同而不管顺序如何的数据结构。所以我建议对数组进行排序并检查它们的内容是否相等。如果你知道数组只包含字符串,你可以用简单的相等来检查项目:

function compare(array1, array2) {
  if (array1.length != array2.length) {
    return false;
  }

  array1 = array1.slice();
  array1.sort();
  array2 = array2.slice();
  array2.sort();

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

  return true;
}

console.log(compare(["abc", "def"], ["def", "abc"])); // true
console.log(compare(["abc", "def"], ["def", "ghi"])); // false

对于更一般的情况,您需要更复杂的相等定义,我建议浏览this question 的答案。

【讨论】:

  • 我认为您对if (array1[i] != array2[i]) { return false; } 中的逻辑有问题。如果找不到匹配项,您不想中断,您应该继续寻找匹配项
  • 如果它们包含相同的项目,即使它们的顺序不同,它们看起来也必须被视为相等。这不会通过你的检查。将是 n^2 次迭代...或者需要在您实施时进行排序。
  • 感谢您的回答。这是最有效的方法吗? JS没有这个操作的内置函数吗?
  • 我想我已经解决了你们的 cmets。我最初误读了这个问题,并期望数组完全相等。现在我使用与 Culme 相同的方法对数组进行排序。
  • Abhijith:我通常使用这种方法。在极端情况下,我会将 array1 中的所有项目作为键放在一个对象中(JavaScript 最接近 Set 数据结构的东西),以便在迭代 array2 时获得恒定时间查找,但我几乎不需要到。
【解决方案2】:

朴素算法:O(N^2)

function compare(array1, array2){
  for (var i = 0; i < array1.length; i++){
    if (array2.indexOf(array1[i]) < 0) return false;
  }
  return true;  
}

更好的一个:(使用排序,O(NLOGN))

function compare(array1, array2){
  array1.sort();
  array2.sort();
  for (var i = 0; i < array1.length; i++){
    if (array1[i] !== array2[i]) return false;
  }
  return true;  
}

【讨论】:

  • 这两个都需要在开始时if(array1.length !== array2.length) { return false } 才能工作。
【解决方案3】:
JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

【讨论】:

【解决方案4】:

统一解决方案:

function compare(a, b){
      var isEqual = false;  
      if (Array.isArray(a) && Array.isArray(b) && a.length == b.length){
          a.sort();
          b.sort();
          var i;
          for (i = 0; i < arr1.length; i++){
              if (a[i] === b[i]){
                  isEqual = true;
              } else{
                  isEqual = false;
                  break;
              }
          }

      }
      return isEqual;
}

var arr1 = ["def", "abc"], arr2 = ["abc", "def"];
console.log(compare(arr2,arr1)); // gives 'true'

console.log(compare(["abc", "def"], ["def", "ghi"])); // gives 'false'

https://jsfiddle.net/ob7e5ye5/4/

【讨论】:

    【解决方案5】:
    function compare(arr1, arr2){
        var match = true
        if(arr1.length != arr2.length){
            match = false
        }
        arr1 = arr1.slice();
        arr1.sort();
        arr2.slice();
        arr2.sort();
        for(var i = 0; i < arr1.length; i++){
            if(arr1[i] != arr2[i]){
                match = false;
            }
        }
        return match;
    }
    
    console.log(compare(["abc", "def"], ["def", "abc"])); // it will return true
    console.log(compare(["abc", "def"], ["def", "ghi"])); // it will return false
    

    【讨论】:

      【解决方案6】:

      我建议遵循 ES6-oneliner

      const compare = (a1, a2) =>
        (a1 = new Set(a1)) &&
        (a2 = new Set(a2)) &&
        a1.size === a2.size &&
        [...a1].every(v => a2.has(v));
      
      1. 通过将数组转换为 Set 来删除重复项(compare(['a', 'a'], ['a', 'b']) 应返回 false)。
      2. 长度比较(compare(['a', 'b'], ['a', 'b', 'c']) 应返回 false)。
      3. 检查第一组项目是否存在于第二组中。

      【讨论】:

      • 这对于a1 = ['foo', 'foo']a2 = ['foo', 'bar']; 将返回true
      • @StephenHarris 谢谢!我申请了Set 转换来解决重复的情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 2012-02-14
      • 2011-08-02
      相关资源
      最近更新 更多