我想比较两个数组。。。理想地、有效地。没有什么稀奇古怪的,如果它们是相同的,那就是真的,如果不是,那就是假的。毫不奇怪,比较运算符似乎不起作用。

var a1 = [1,2,3];
var a2 = [1,2,3];
console.log(a1==a2);    // Returns false
console.log(JSON.stringify(a1)==JSON.stringify(a2));    // Returns true

JSON对每个数组进行编码,但是否有一种更快或“更好”的方法来简单地比较数组而不必遍历每个值?


当前回答

我相信简单的JS和ECMAScript 2015,这很好理解。

var is_arrays_compare_similar = function (array1, array2) {

    let flag = true;

    if (array1.length == array2.length) {

        // check first array1 object is available in array2 index
        array1.every( array_obj => {
            if (flag) {
                if (!array2.includes(array_obj)) {
                    flag = false;
                }
            }
        });
        
        // then vice versa check array2 object is available in array1 index
        array2.every( array_obj => {
            if (flag) {
                if (!array1.includes(array_obj)) {
                    flag = false;
                }
            }
        });

        return flag;
    } else {
        return false;
    }
    
}

其他回答

此外,我还根据需要将Thomas的解决方案转换为无需排序的比较。

Array.prototype.equalsFreeOrder = function (array) {
    var isThisElemExist;
    if (!array)
        return false;

    if (this.length != array.length)
        return false;

    for (var i = 0; i < this.length; i++) {
        isThisElemExist = false;
        for (var k = 0; k < this.length; k++) {
            if (this[i] instanceof Array && array[k] instanceof Array) {
                if (this[i].equalsFreeOrder(array[k]))
                    isThisElemExist = true;
            }
            else if (this[i] == array[k]) {
                isThisElemExist = true;
            }
        }
        if (!isThisElemExist)
            return false;
    }
    return true;
}

虽然这个问题的最佳答案是正确和良好的,但提供的代码可能需要一些改进。

下面是我自己比较数组和对象的代码。代码简短而简单:

Array.prototype.equals = function(otherArray) {
  if (!otherArray || this.length != otherArray.length) return false;
  return this.reduce(function(equal, item, index) {
    var otherItem = otherArray[index];
    var itemType = typeof item, otherItemType = typeof otherItem;
    if (itemType !== otherItemType) return false;
    return equal && (itemType === "object" ? item.equals(otherItem) : item === otherItem);
  }, true);
};

if(!Object.prototype.keys) {
  Object.prototype.keys = function() {
    var a = [];
    for (var key in this) {
      if (this.hasOwnProperty(key)) a.push(key);
    }
    return a;
  }
  Object.defineProperty(Object.prototype, "keys", {enumerable: false});
}

Object.prototype.equals = function(otherObject) {
  if (!otherObject) return false;
  var object = this, objectKeys = object.keys();
  if (!objectKeys.equals(otherObject.keys())) return false;
  return objectKeys.reduce(function(equal, key) {
    var value = object[key], otherValue = otherObject[key];
    var valueType = typeof value, otherValueType = typeof otherValue;
    if (valueType !== otherValueType) return false;
    // this will call Array.prototype.equals for arrays and Object.prototype.equals for objects
    return equal && (valueType === "object" ? value.equals(otherValue) : value === otherValue);
  }, true);
}
Object.defineProperty(Object.prototype, "equals", {enumerable: false});

此代码支持嵌套在对象中的数组和嵌套在数组中的对象。

您可以在下面的repl中看到一整套测试并自己测试代码:https://repl.it/Esfz/3

代码高尔夫

有很多答案表明如何有效地比较数组。

以下是比较两个int或(字符串)数组的最短方法,以代码字节为单位。

常量a=[1,2,3]常量b=[1,2,3]console.log(“1.”,a.join()==b.join(())console.log(“2.”,a.join()==[].join())console.log(“3.”,1+a==1+b)console.log(“4.”,1+[]==1+b)//甚至更短console.log(“4.b)”,a==“”+b)//误报(见缺陷)console.log(“5.”,1+[“3”]==1+[3])//类型差异console.log(“6.”,1+[“1,2”]==1+[“1”,“2”])

解释

这是因为当使用+运算符时,类型会自动转换为允许串联。在这种情况下,1和[1,2,3]都被转换为字符串。

在内部,JavaScript使用[1,2,3].join()将数组转换为字符串,然后将它们相加,得到11,2,3。在两个数组上执行此操作时,可以简单地使用==或==来比较两个字符串。

缺陷

使用此技术,比较不关心要比较的数组中的元素是否属于不同类型。由于字符串转换,[1,2]将等于[“1”,“2”]。

编辑:正如评论中指出的,比较字符串数组可能会产生误报,例如[“1,2”]等于[“1”,“2”]。如果您确信这些情况从未发生过(例如,在许多代码高尔夫挑战中),这一点就不重要了。

免责声明

虽然这对于代码高尔夫很有用,但可能不应该在生产代码中使用。指出的两个缺陷也无助于此。

当两个数组具有相同的元素但顺序不同时,代码将无法正确处理这种情况。

看看我的代码,看看你的示例,它比较了两个元素为数字的数组,你可以修改或扩展它以用于其他元素类型(通过使用.jjoin()而不是.toString())。

变量a1=[1,2,3];变量a2=[1,2,3];const arrayAreEqual=a1.sort().toString()==a2.sort(().toString();//如果两个数组具有相同的元素,则为true,否则为falseconsole.log(arrayAreEqual);

JSON.stringify(collectionNames).includes(JSON.stringify(sourceNames)) ?  array.push(collection[i]) : null

我就是这样做的。