本文翻译自:How to compare arrays in JavaScript?

I'd like to compare two arrays... ideally, efficiently. 我想比较两个数组...理想地,有效地比较。 Nothing fancy, just true if they are identical, and false if not. 没有幻想,如果相同则为true ,否则为false Not surprisingly, the comparison operator doesn't seem to work. 毫不奇怪,比较运算符似乎不起作用。

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 encoding each array does, but is there a faster or "better" way to simply compare arrays without having to iterate through each value? 每个数组都可以使用JSON编码,但是有没有一种更快或更“更好”的方法来简单地比较数组而不必遍历每个值?


#1楼

参考:https://stackoom.com/question/Wssa/如何在JavaScript中比较数组


#2楼

To compare arrays, loop through them and compare every value: 要比较数组,请遍历它们并比较每个值:

Comparing arrays: 比较数组:

// Warn if overriding existing method
if(Array.prototype.equals)console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {// if the other array is a falsy value, returnif (!array)return false;// compare lengths - can save a lot of time if (this.length != array.length)return false;for (var i = 0, l=this.length; i < l; i++) {// Check if we have nested arraysif (this[i] instanceof Array && array[i] instanceof Array) {// recurse into the nested arraysif (!this[i].equals(array[i]))return false;       }           else if (this[i] != array[i]) { // Warning - two different object instances will never be equal: {x:20} != {x:20}return false;   }           }       return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

Usage: 用法:

[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;

You may say " But it is much faster to compare strings - no loops... " well, then you should note there ARE loops. 您可能会说“ 但是比较字符串要快得多-没有循环... ”,那么,您应该注意有ARE循环。 First recursive loop that converts Array to string and second, that compares two strings. 第一个递归循环将Array转换为字符串,第二个递归循环比较两个字符串。 So this method is faster than use of string . 因此,此方法比使用string更快 。

I believe that larger amounts of data should be always stored in arrays, not in objects. 我认为,应将大量数据始终存储在数组中,而不是对象中。 However if you use objects, they can be partially compared too. 但是,如果使用对象,也可以部分比较它们。
Here's how: 这是如何做:

Comparing objects: 比较对象:

I've stated above, that two object instances will never be equal, even if they contain same data at the moment: 上面我已经说过,即使此时两个对象实例包含相同的数据,它们也永远不会相等:

({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666})  //false

This has a reason, since there may be, for example private variables within objects. 这是有原因的,因为在对象中可能存在例如私有变量。

However, if you just use object structure to contain data, comparing is still possible: 但是,如果仅使用对象结构来包含数据,则仍然可以进行比较:

Object.prototype.equals = function(object2) {//For the first loop, we only check for typesfor (propName in this) {//Check for inherited methods and properties - like .equals itself//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty//Return false if the return value is differentif (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {return false;}//Check instance typeelse if (typeof this[propName] != typeof object2[propName]) {//Different types => not equalreturn false;}}//Now a deeper check using other objects property namesfor(propName in object2) {//We must check instances anyway, there may be a property that only exists in object2//I wonder, if remembering the checked values from the first loop would be faster or not if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {return false;}else if (typeof this[propName] != typeof object2[propName]) {return false;}//If the property is inherited, do not check any more (it must be equa if both objects inherit it)if(!this.hasOwnProperty(propName))continue;//Now the detail check and recursion//This returns the script back to the array comparing/**REQUIRES Array.equals**/if (this[propName] instanceof Array && object2[propName] instanceof Array) {// recurse into the nested arraysif (!this[propName].equals(object2[propName]))return false;}else if (this[propName] instanceof Object && object2[propName] instanceof Object) {// recurse into another objects//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");if (!this[propName].equals(object2[propName]))return false;}//Normal value comparison for strings and numberselse if(this[propName] != object2[propName]) {return false;}}//If everything passed, let's say YESreturn true;
}

However, remember that this one is to serve in comparing JSON like data, not class instances and other stuff. 但是,请记住,这是用于比较JSON之类的数据,而不是类实例和其他内容。 If you want to compare mor complicated objects, look at this answer and it's superlong function . 如果您想比较复杂的物体,请看这个答案,它是超长函数 。
To make this work with Array.equals you must edit the original function a little bit: 为了使它与Array.equals一起Array.equals您必须对原始函数进行一些编辑:

...// Check if we have nested arraysif (this[i] instanceof Array && array[i] instanceof Array) {// recurse into the nested arraysif (!this[i].equals(array[i]))return false;}/**REQUIRES OBJECT COMPARE**/else if (this[i] instanceof Object && array[i] instanceof Object) {// recurse into another objects//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");if (!this[i].equals(array[i]))return false;}else if (this[i] != array[i]) {
...

I made a little test tool for both of the functions . 我为这两个功能都做了一个小测试工具 。

Bonus: Nested arrays with indexOf and contains 奖励:具有indexOfcontains嵌套数组

Samy Bencherif has prepared useful functions for the case you're searching for a specific object in nested arrays, which are available here: https://jsfiddle.net/SamyBencherif/8352y6yw/ Samy Bencherif为您在嵌套数组中搜索特定对象的情况准备了有用的功能,可在以下位置找到: https : //jsfiddle.net/SamyBencherif/8352y6yw/


#3楼

In my case compared arrays contain only numbers and strings. 就我而言,比较数组仅包含数字和字符串。 This function will show you if arrays contain same elements. 此函数将显示数组是否包含相同的元素。

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

Let's test it! 让我们测试一下!

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

#4楼

Herer's my solution: 这是我的解决方案:

/*** Tests two data structures for equality* @param {object} x* @param {object} y* @returns {boolean}*/
var equal = function(x, y) {if (typeof x !== typeof y) return false;if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;if (typeof x === 'object') {for (var p in x) if (x.hasOwnProperty(p)) {if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;if (typeof x[p] !== typeof y[p]) return false;if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } elseif (x[p] !== y[p]) return false;}} else return x === y;return true;
};

Works with any nested data structure, and obviously ignores objects' methods. 适用于任何嵌套数据结构,并且显然会忽略对象的方法。 Don't even think of extending Object.prototype with this method, when I tried this once, jQuery broke ;) 甚至不用考虑用这种方法扩展Object.prototype,当我尝试过一次时,jQuery坏了;)

For most arrays it's still faster than most of serialization solutions. 对于大多数阵列,它仍然比大多数序列化解决方案要快。 It's probably the fastest compare method for arrays of object records. 对于对象记录数组,这可能是最快的比较方法。


#5楼

Extending Tomáš Zato idea. 扩展TomášZato的想法。 Tomas's Array.prototype.compare should be infact called Array.prototype.compareIdentical. Tomas的Array.prototype.compare实际上应该称为Array.prototype.compareIdentical。

It passes on: 它继续:

[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 2]]) === false;
[1, "2,3"].compareIdentical ([1, 2, 3]) === false;
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].compareIdentical ([1, 2, 1, 2]) === true;

But fails on: 但失败:

[[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]])

Here is better (in my opinion) version: 这是更好的版本(在我看来):

Array.prototype.compare = function (array) {// if the other array is a falsy value, returnif (!array)return false;// compare lengths - can save a lot of timeif (this.length != array.length)return false;this.sort();array.sort();for (var i = 0; i < this.length; i++) {// Check if we have nested arraysif (this[i] instanceof Array && array[i] instanceof Array) {// recurse into the nested arraysif (!this[i].compare(array[i]))return false;}else if (this[i] != array[i]) {// Warning - two different object instances will never be equal: {x:20} != {x:20}return false;}}return true;
}

http://jsfiddle.net/igos/bcfCY/ http://jsfiddle.net/igos/bcfCY/


#6楼

Building off Tomáš Zato's answer, I agree that just iterating through the arrays is the fastest. 基于TomášZato的答案,我同意仅迭代数组是最快的。 Additionally (like others have already stated), the function should be called equals/equal, not compare. 另外(就像其他人已经说过的那样),该函数应称为等于/等于,而不是比较。 In light of this, I modified the function to handle comparing arrays for similarity - ie they have the same elements, but out of order - for personal use, and thought I'd throw it on here for everyone to see. 有鉴于此,我修改了该函数以处理比较数组的相似性(即它们具有相同的元素,但顺序混乱)供个人使用,并认为我会将其放在这里供大家查看。

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;
}

This function takes an additional parameter of strict that defaults to true. 此函数采用默认为true的strict附加参数。 This strict parameter defines if the arrays need to be wholly equal in both contents and the order of those contents, or simply just contain the same contents. 这个严格的参数定义数组在内容和内容顺序上是否需要完全相等,或者仅包含相同的内容。

Example: 例:

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 1arr1.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

I've also written up a quick jsfiddle with the function and this example: 我还使用该函数和此示例编写了一个快速的jsfiddle:
http://jsfiddle.net/Roundaround/DLkxX/ http://jsfiddle.net/Roundaround/DLkxX/

如何在JavaScript中比较数组?相关推荐

  1. javascript字典中添加数组_如何在JavaScript中使用数组方法:Mutator方法

    JavaScript中的数组由元素列表组成.JavaScript有许多有用的内置方法来处理数组.修改原始数组的方法称为mutator方法,返回新值或表示的方法称为accessor方法.在本教程中,我们 ...

  2. 如何在 JavaScript 中清空数组?

    问: 这个问题的答案是社区的努力.编辑现有答案以改进这篇文章.它目前不接受新的答案或交互. 有没有办法清空数组,如果可能的话,可以使用 .remove()? 例如, A = [1,2,3,4]; 我怎 ...

  3. JS For循环教程–如何在JavaScript中遍历数组

    This article will provide you with a solid understanding of exactly how to iterate over an Array dat ...

  4. 如何在JavaScript中克隆数组

    JavaScript has many ways to do anything. I've written on 10 Ways to Write pipe/compose in JavaScript ...

  5. hdfs中与file数组类似的数组_如何在 JavaScript 中克隆数组

    作者:Yazeed Bzadough 译者:allen JavaScript 有很多方法可以做任何事情,现在我们研究数组. 1.扩展运算符(浅拷贝) 自从 ES6 发布以来,这一直是最受欢迎的方法.这 ...

  6. java怎么把数组清空_如何在JavaScript中清空数组?

    有没有一种方法可以清空数组,如果可以的话,可以使用.remove()吗? 例如, A = [1,2,3,4]; 我该如何清空? #1楼 清除现有数组A : 方法1 (这是我对问题的原始回答) A = ...

  7. 在 JavaScript 中清空数组

    该数组是存储在一个方便的索引集中的项目集合.如果我们想清空一个包含多个项目的数组怎么办? 本教程介绍了如何在 JavaScript 中清空数组的不同方法 1.将数组设置为大小为零的新数组 这是最快的方 ...

  8. JavaScript中清空数组

    如何在JavaScript中清空数组 方法一:将数组变量设置为大小为零的新数组 HTML代码: <button onclick="empty()">单击可清空 < ...

  9. 如何在JavaScript中获取字符串数组的字符串?

    本文翻译自:How do you get a string to a character array in JavaScript? How do you get a string to a chara ...

最新文章

  1. php 数组与数组之间去重,PHP开发中一维数组与二维数组去重功能实现教程
  2. 迅为linux下串口,迅为iMX6UL开发板多路串口开发板接口详解
  3. SAP系统中在发布了webservice,获得了WSDN地址后,外部系统怎么传数据到SAP?
  4. Git撤销修改场景及对应指令(checkout、reset、revert)详解
  5. 一篇总结的很好的Spring data jpa 文章,里面包含多种查询方式,可以结合api使用
  6. LeetCode 长度最小的子数组
  7. sublime text常用快捷键整理
  8. 【算法导论】第5章,概率分析和随机算法
  9. 一个树杈y图片_鬼脸纹:黄花梨树上一个树杈,反映到主干上时,会形成一个疖痕...
  10. java之接口适配器
  11. 【Android】12.0 第12章 Intent及其过滤器—本章示例主界面
  12. Greasy Fork 视频网页全屏脚本
  13. Unity关节的使用和举例,布娃娃系统
  14. 2353410-06-5,TCO-PEG8-TFP ester单分散交联剂,含有TCO部分和PFP酯
  15. 图计算库 igraph 在 windows 10 上的编译安装
  16. Excel通过poi设置折线图样式
  17. visio图形大小参数驱动
  18. word毕业论文题注自动编号设置——第一章与图1-1
  19. linux dvb设备信息,Linux DVB api 笔记
  20. MOS管驱动电路分析及详解-KIA MOS管

热门文章

  1. 在本机用Toad远程连接Oracle数据库
  2. Android面试题目之二:整形转换为字符串
  3. 算法--------二叉树的中序遍历
  4. 关于android 5.0报错:dlopen failed: couldn't map ... Permission denied
  5. 第三周项目三-输出星号图(3)
  6. java 字符串常用函数_Java学习(5)——字符串常用函数
  7. 【Android View基础】View中几个容易混淆的距离及坐标量
  8. topcoder13444
  9. sonar:查询全部项目的bug和漏洞总数(只查询阻断/严重/主要级别)
  10. 安装的 Python 版本太多互相干扰?pyenv 建议了解一下。