比较javascript中的数组顺序并不重要

时间:2017-12-06 03:53:50

标签: javascript arrays

我正在学习Javascript,我在SO上看到了一个函数,用于比较数组以检查它们是否相同。但是,如果两个数组是[string1,string2]& [字符串2,字符串1]。基本上,这两个职位互换。代码如下:

function _compareArrays(arr1,arr2){
    var result = arr1 != null && arr2 != null && arr1.length == arr2.length && arr1.every(function(element) {
            return arr2.indexOf(element);
        });
    return result ;
}

但是,我希望这两个数组返回相同。所以,我将.every更改为.indexOf(),它似乎有效。但是,我有一个疑问,计数器究竟是如何增加的,以确保对每个元素进行比较? 我的意思是,就像在C ++中一样,我们这样做,

for (int i = 0; i < 10; i++)
    if (arr1[i] == arr2[i]
      cout<<"Elements are same\n";

在这里,我有一个明确的i++,它会递增计数器。如何在上述功能中发生?

谢谢!

3 个答案:

答案 0 :(得分:2)

将数组转换为对象。将数组值转换为键及其各自的计数值作为其值。当你只遍历数组一次时,这会更高效。

function compare(a, b) {
  if (a.length !== b.length) {
    return false;
  }
  let set = {};
  a.forEach((i) => {
    if (set[i] !== undefined) {
      set[i]++;
    } else {
      set[i] = 1;
    }
  });
  let difference = b.every((i) => {
    if (set[i] === undefined) {
      return false;
    } else {
      set[i]--;
      if (set[i] === 0) {
        delete set[i];
      }
      return true;
    }
  });
  return Object.keys(set) == 0 && difference;
}

第一个数组上的第一个循环初始化set(对象),第二个数组上的第二个循环减去计数,并在计数达到0时删除键。如果找不到键或者该组没有在程序结束时为空,那么数组就不相似了。

答案 1 :(得分:1)

您目前遇到以下问题:

  1. 这两个数组会返回true(我希望您明白这不是特定于这两个数组):[1, 2, 2][1,1,2]。这个问题是我在下面的解决方案中匹配后将索引设置为undefined的原因。

  2. indexOf为无法找到的元素返回-1,如果可以找到该元素,则返回任意数字>= 0-1是真实的,所以如果一个元素无法找到,您的比较将返回true,而0是假的,因此如果元素位于第二个数组的第一个索引中,您的方法将返回false(这意味着由于false ...),整个事情将成为every。因此,您应该在~调用结果indexOf之前添加~arr2.indexOf(element)

    参见this Bitwise Not运算符(~)上的MDN页面以及它如何解决 我提到的indexOf问题。

    我还建议您查看我的this回答关于truthy / falsy值以及它们与&&||的互动方式。

  3. 所以试试这个(这主要是你的例子,除了没有indexOf使用,我已经修复了问题#2):

    function _compareArrays(arr1,arr2){
      if(!(arr1 != null && arr2 != null && arr1.length == arr2.length)) {
        return false;
      }
    
      /* copy the arrays so that the original arrays are not affected when we set the indices to "undefined" */
      arr1 = [].concat(arr1);
      arr2 = [].concat(arr2);
    
      return arr1.every(function(element, index) {
        return arr2.some(function(e, i) {
          return e === element && (arr2[i] = undefined, true);
        });
      });
    }
        
    var x = ["str", "boo", "str"];
    var y = ["boo", "str", "str"];
    var z = ["abc", "def", "ghi"]    
    
    console.log(_compareArrays(x, y));
    console.log(_compareArrays(x, z));
    console.log(_compareArrays(z, z));

    如果数组中有任何undefined个元素,它将无效。

答案 2 :(得分:0)

所以最快的方法是对两个数组进行排序,然后逐个元素比较每个元素。这需要2n * log(n) + n时间,而不是n 2 时间。

function compareArrays(arr1, arr2){
  if(arr1.length !== arr2.length) return false;

  // implement custom sort if necessary
  arr1.sort();
  arr2.sort();

  // use normal for loop so we can return immediately if not equal
  for(let i=0; i<arr1.length; i++){
    if(arr1[i] !== arr2[i]) return false;
  }

  return true;
}