Javascript 如何知道两个数组是否具有相同的值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6229197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:51:08  来源:igfitidea点击:

How to know if two arrays have the same values

javascriptarrayscompare

提问by Carlos Precioso

I have these two arrays: one is filled with information from an ajax request and another stores the buttons the user clicks on. I use this code (I filled with sample numbers):

我有这两个数组:一个填充来自 ajax 请求的信息,另一个存储用户点击的按钮。我使用此代码(我填充了示例编号):

var array1 = [2, 4];
var array2 = [4, 2]; //It cames from the user button clicks, so it might be disordered.
array1.sort(); //Sorts both Ajax and user info.
array2.sort();
if (array1==array2) {
    doSomething();
}else{
    doAnotherThing();
}

But it always gives false, even if the two arrays are the same, but with different name. (I checked this in Chrome's JS Console). So, is there any way I could know if these two arrays contain the same? Why is it giving false? How can I know which values in the first array are not in the second?

但它总是给出false,即使两个数组相同,但名称不同。(我在 Chrome 的 JS 控制台中检查了这个)。那么,有什么办法可以知道这两个数组是否包含相同的内容?为什么要给予false?我怎么知道第一个数组中的哪些值不在第二个数组中?

采纳答案by Maciej Krawczyk

function arraysEqual(_arr1, _arr2) {

    if (!Array.isArray(_arr1) || ! Array.isArray(_arr2) || _arr1.length !== _arr2.length)
      return false;

    var arr1 = _arr1.concat().sort();
    var arr2 = _arr2.concat().sort();

    for (var i = 0; i < arr1.length; i++) {

        if (arr1[i] !== arr2[i])
            return false;

    }

    return true;

}

Note that this doesn't modify original arrays unlike a previous answer.

请注意,与之前的答案不同,这不会修改原始数组。

回答by kennebec

If your array items are not objects- if they are numbers or strings, for example, you can compare their joined strings to see if they have the same members in any order-

如果您的数组项不是对象-例如,如果它们是数字或字符串,您可以比较它们的连接字符串以查看它们是否按任何顺序具有相同的成员-

var array1= [10, 6, 19, 16, 14, 15, 2, 9, 5, 3, 4, 13, 8, 7, 1, 12, 18, 11, 20, 17];
var array2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17];

if(array1.sort().join(',')=== array2.sort().join(',')){
    alert('same members');
}
else alert('not a match');

回答by Technotronic

If you want to check only if two arrays have same values (regardless the number of occurrences and order of each value) you could do this by using lodash:

如果您只想检查两个数组是否具有相同的值(不管每个值的出现次数和顺序),您可以使用lodash来执行此操作

_.isEmpty(_.xor(array1, array2))

Short, simple and pretty!

简短,简单,漂亮!

回答by isakkarlsson

Array.prototype.compare = function(testArr) {
    if (this.length != testArr.length) return false;
    for (var i = 0; i < testArr.length; i++) {
        if (this[i].compare) { //To test values in nested arrays
            if (!this[i].compare(testArr[i])) return false;
        }
        else if (this[i] !== testArr[i]) return false;
    }
    return true;
}

var array1 = [2, 4];
var array2 = [4, 2];
if(array1.sort().compare(array2.sort())) {
    doSomething();
} else {
    doAnotherThing();
}

Maybe?

也许?

回答by Max Heiber

Why your code didn't work

为什么你的代码不起作用

JavaScript has primitive data typesand non-primitive data types.

JavaScript 有原始数据类型和非原始数据类型。

For primitive data types, ==and ===check whether the things on either side of the bars have the same value. That's why 1 === 1is true.

对于原始数据类型,=====检查是否在酒吧两边的东西具有相同的值。这就是为什么1 === 1是真的。

For non-primitive data types like arrays, ==and ===check for reference equality. That is, they check whether arr1and arr2are the same object. In your example, the two arrays have the same objects in the same order, but are not equivalent.

对于非原始数据类型(如数组),=====检查引用相等性。也就是说,它们检查arr1和是否arr2是同一个对象。在您的示例中,两个数组具有相同顺序的相同对象,但并不等效。

Solutions

解决方案

Two arrays, arr1and arr2, have the same members if and only if:

两个数组arr1andarr2具有相同的成员当且仅当:

  • Everything in arr2is in arr1
  • 一切都arr2arr1

AND

  • Everything in arr1is in arr2
  • 一切都arr1arr2

So this will do the trick (ES2016):

所以这可以解决问题(ES2016):

const containsAll = (arr1, arr2) => 
                arr2.every(arr2Item => arr1.includes(arr2Item))

const sameMembers = (arr1, arr2) => 
                        containsAll(arr1, arr2) && containsAll(arr2, arr1);

sameMembers(arr1, arr2); // `true`

This second solution using Underscoreis closer to what you were trying to do:

使用Underscore 的第二个解决方案更接近您尝试执行的操作:

arr1.sort();
arr2.sort();

_.isEqual(arr1, arr2); // `true`

It works because isEqualchecks for "deep equality," meaning it looks at more than just reference equality and compares values.

它之所以有效是因为isEqual检查“深度相等”,这意味着它不仅仅查看引用相等和比较值。

A solution to your third question

解决你的第三个问题

You also asked how to find out which things in arr1are not contained in arr2.

你还问我如何找出哪些东西arr1在不包含arr2

This will do it (ES2015):

这将做到(ES2015):

const arr1 = [1, 2, 3, 4];
const arr2 = [3, 2, 1];

arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]`

You could also use Underscore's difference: method:

您还可以使用 Underscore 的difference: 方法:

_.difference(arr1, arr2); // `[4]`

UPDATE

更新

See @Redu's comment—my solution is for sameMembers, but what you may have in mind is sameMembersInOrderalso-known-as deepEquals.

请参阅@Redu 的评论——我的解决方案是针对sameMembers,但您可能想到的是sameMembersInOrder也称为deepEquals

UPDATE 2

更新 2

If you don't care about the order of the members of the arrays, ES2015+'s Setmay be a better data structure than Array. See the MDN notes on how to implement isSupersetand differenceusing dangerous monkey-patching.

如果你不关心数组成员的顺序,ES2015+Set可能是比Array. 请参阅有关如何实施isSupersetdifference使用危险的猴子补丁的MDN 说明

回答by Sandeep

Object equality check:JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

对象相等性检查:JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

The above test also works with arrays of objects in which case use a sort function as documented in http://www.w3schools.com/jsref/jsref_sort.asp

上述测试也适用于对象数组,在这种情况下,请使用http://www.w3schools.com/jsref/jsref_sort.asp 中记录的排序函数

Might suffice for small arrays with flat JSON schemas.

对于具有扁平 JSON 模式的小型数组可能就足够了。

回答by canbax

Our aim is basically to check whether 2 arrays are equal sets. setis the mathematically defined set. Fastest sorting asymptotically takes O(nlog(n))time. So If you sort an array, it would take at least O(nlog(n))time. But you can do this task faster, which asymptotically takes O(n)time (average case not worst case) with a dictionary data structure. In JS, a dictionary is simply an object with keys and values.

我们的目标基本上是检查 2 个数组是否是相等的集合。set是数学定义的set。最快的排序渐近花费O(nlog(n))时间。因此,如果对数组进行排序,则至少需要O(nlog(n))时间。但是您可以更快地完成此任务,使用字典数据结构渐近地花费O(n)时间(平均情况不是最坏的情况)。在 JS 中,字典只是一个带有键和值的对象。

// assumes array elements are primitive types
function areArraysEqualSets(a1, a2) {
  let superSet = {};
  for (let i = 0; i < a1.length; i++) {
    const e = a1[i] + typeof a1[i];
    superSet[e] = 1;
  }

  for (let i = 0; i < a2.length; i++) {
    const e = a2[i] + typeof a2[i];
    if (!superSet[e]) {
      return false;
    }
    superSet[e] = 2;
  }

  for (let e in superSet) {
    if (superSet[e] === 1) {
      return false;
    }
  }

  return true;
}

Note that this function works with arrays of primitive types and assumes a1 and a2 are arrays.

请注意,此函数适用于原始类型的数组,并假定 a1 和 a2 是数组。

回答by Andrew

When you compare those two arrays, you're comparing the objects that represent the arrays, not the contents.

当您比较这两个数组时,您是在比较表示数组的对象,而不是内容。

You'll have to use a function to compare the two. You could write your own that simply loops though one and compares it to the other after you check that the lengths are the same.

您必须使用一个函数来比较两者。您可以编写自己的代码,在检查长度是否相同后,简单地循环一个循环并将其与另一个进行比较。

回答by camslice

Simple solution for shallow equality using ES6:

使用 ES6 实现浅等式的简单解决方案:

const arr1test = arr1.slice().sort()
const arr2test = arr2.slice().sort()
const equal = !arr1test.some((val, idx) => val !== arr2test[idx])

Creates shallow copies of each array and sorts them. Then uses some()to loop through arr1testvalues, checking each value against the value in arr2testwith the same index. If all values are equal, some()returns false, and in turn equalevaluates to true.

创建每个数组的浅拷贝并对其进行排序。然后使用some()循环遍历arr1test值,根据arr2test具有相同索引的值检查每个值。如果所有值都相等,则some()返回false,然后equal计算结果为true

Could also use every(), but it would have to cycle through every element in the array to satisfy a trueresult, whereas some()will bail as soon as it finds a value that is not equal:

也可以使用every(),但它必须循环遍历数组中的每个元素才能满足true结果,而some()一旦找到不相等的值就会退出:

const equal = arr1test.every((val, idx) => val === arr2test[idx])

回答by Ben Carp

Using ES6

使用 ES6

We'll use Ramda's equalsfunction, but instead we can use Lodash's or Underscore's isEqual:

我们将使用 Ramda 的equals函数,但我们可以使用 Lodash 或 Underscore 的函数isEqual

const R = require('ramda');

const arraysHaveSameValues = (arr1, arr2) => R.equals( [...arr1].sort(), [...arr2].sort() )

Using the spread opporator, we avoid mutating the original arrays, and we keep our function pure.

使用扩展运算符,我们避免改变原始数组,并保持我们的函数纯。