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

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


当前回答

尽管这有很多答案,但我相信这会有所帮助:

const newArray = [ ...new Set( [...arr1, ...arr2] ) ]

这个问题中没有说明数组的结构是什么样子的,所以如果你确定你的数组中既没有嵌套的数组也没有对象(这发生在我身上,这就是我得到这个答案的原因),上面的代码就会起作用。

发生的情况是,我们使用扩展运算符(…)将两个数组合并,然后使用Set消除任何重复。一旦你有了这些,你就可以比较它们的大小,如果三个数组都有相同的大小,那么你就可以去做了。

这个答案也忽略了元素的顺序,正如我所说的,确切的情况发生在我身上,所以也许有人在同样的情况下会在这里结束(正如我所做的那样)。


编辑1。

回答德米特里·格林科的问题:“你为什么在这里使用扩展运算符(…)-……新设置?它不起作用”

考虑以下代码:

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

你会得到

[ Set { 'a', 'b', 'c' } ]

为了使用该值,您需要使用一些Set财产(请参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set).另一方面,当您使用此代码时:

const arr1 = [ 'a', 'b' ]
const arr2 = [ 'a', 'b', 'c' ]
const newArray = [ ...new Set( [...arr1, ...arr2] ) ]
console.log(newArray)

你会得到

[ 'a', 'b', 'c' ]

这就是区别,前者会给我一个集合,它也会工作,因为我可以得到集合的大小,但后者给了我所需的数组,更直接的是分辨率。

其他回答

我认为这是使用JSON字符串最简单的方法,在某些情况下可能是最好的解决方案:

JSON.stringify(a1) === JSON.stringify(a2);

这将对象a1和a2转换为字符串,以便对它们进行比较。在大多数情况下,顺序很重要,因为它可以使用上面答案之一中所示的排序算法对对象进行排序。

请注意,您不再比较对象,而是比较对象的字符串表示形式。这可能不是你想要的。

根据TomášZato的回答,我同意仅迭代数组是最快的。此外(就像其他人已经说过的那样),函数应该被称为equals/equal,而不是compare。考虑到这一点,我修改了该函数,以处理比较数组的相似性(即它们具有相同的元素,但没有顺序),以供个人使用,并认为我将把它放在这里让大家看到。

Array.prototype.equals = function (array, strict) {
    if (!array)
        return false;

    if (arguments.length == 1)
        strict = true;

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

    for (var i = 0; i < this.length; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i], strict))
                return false;
        }
        else if (strict && this[i] != array[i]) {
            return false;
        }
        else if (!strict) {
            return this.sort().equals(array.sort(), true);
        }
    }
    return true;
}

此函数接受默认为true的strict附加参数。这个严格的参数定义数组是否需要在内容和这些内容的顺序上完全相等,或者仅仅包含相同的内容。

例子:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3];  // Loosely equal to 1
var arr3 = [2, 2, 3, 4];  // Not equal to 1
var arr4 = [1, 2, 3, 4];  // Strictly equal to 1

arr1.equals(arr2);         // false
arr1.equals(arr2, false);  // true
arr1.equals(arr3);         // false
arr1.equals(arr3, false);  // false
arr1.equals(arr4);         // true
arr1.equals(arr4, false);  // true

我还编写了一个函数的快速jsfiddle,以及这个示例:http://jsfiddle.net/Roundaround/DLkxX/

这是一个字体版本:

//https://stackoverflow.com/a/16436975/2589276
export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
    if (a === b) return true
    if (a == null || b == null) return false
    if (a.length != b.length) return false

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

//https://stackoverflow.com/a/16436975/2589276
export function arraysDeepEqual<T>(a: Array<T>, b: Array<T>): boolean {
    return JSON.stringify(a) === JSON.stringify(b)
}

摩卡的一些测试用例:

it('arraysEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','apple','banana']
    let f = ['car','apple','banana']
    let g = ['car','apple','banan8']

    expect(arraysEqual(a, b)).to.equal(true)
    expect(arraysEqual(c, d)).to.equal(true)
    expect(arraysEqual(a, d)).to.equal(false)
    expect(arraysEqual(e, f)).to.equal(true)
    expect(arraysEqual(f, g)).to.equal(false)
})

it('arraysDeepEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','apple','banana']
    let f = ['car','apple','banana']
    let g = ['car','apple','banan8']
    let h = [[1,2],'apple','banan8']
    let i = [[1,2],'apple','banan8']
    let j = [[1,3],'apple','banan8']

    expect(arraysDeepEqual(a, b)).to.equal(true)
    expect(arraysDeepEqual(c, d)).to.equal(true)
    expect(arraysDeepEqual(a, d)).to.equal(false)
    expect(arraysDeepEqual(e, f)).to.equal(true)
    expect(arraysDeepEqual(f, g)).to.equal(false)
    expect(arraysDeepEqual(h, i)).to.equal(true)
    expect(arraysDeepEqual(h, j)).to.equal(false)
})

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

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

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

在我的例子中,比较数组只包含数字和字符串。此函数将显示数组是否包含相同的元素。

function are_arrs_match(arr1, arr2){
    return arr1.sort().toString() === arr2.sort().toString()
}

让我们测试一下!

arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]

console.log (are_arrs_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false