我想比较两个数组。。。理想地、有效地。没有什么稀奇古怪的,如果它们是相同的,那就是真的,如果不是,那就是假的。毫不奇怪,比较运算符似乎不起作用。
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对每个数组进行编码,但是否有一种更快或“更好”的方法来简单地比较数组而不必遍历每个值?
此脚本比较对象、数组和多维数组
function compare(a,b){
var primitive=['string','number','boolean'];
if(primitive.indexOf(typeof a)!==-1 && primitive.indexOf(typeof a)===primitive.indexOf(typeof b))return a===b;
if(typeof a!==typeof b || a.length!==b.length)return false;
for(i in a){
if(!compare(a[i],b[i]))return false;
}
return true;
}
第一行检查它是否为原始类型。如果是,则比较这两个参数。
如果它们是对象。它遍历Object并递归检查每个元素。
用法:
var a=[1,2,[1,2]];
var b=[1,2,[1,2]];
var isEqual=compare(a,b); //true
另一种代码很少的方法(使用Array reduce和Array includes):
arr1.length == arr2.length && arr1.reduce((a, b) => a && arr2.includes(b), true)
如果还要比较顺序的相等性:
arr1.length == arr2.length && arr1.reduce((a, b, i) => a && arr2[i], true)
长度检查确保一个数组中的元素集不仅仅是另一个数组的子集。缩减器用于遍历一个数组并搜索另一个数组中的每个项。如果找不到一项,reduce函数将返回false。在第一个示例中,正在测试是否包含元素第二个示例也检查订单
虽然这个问题的最佳答案是正确和良好的,但提供的代码可能需要一些改进。
下面是我自己比较数组和对象的代码。代码简短而简单:
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
我们可以用功能性的方式(https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/every)
function compareArrays(array1, array2) {
if (array1.length === array2.length)
return array1.every((a, index) => a === array2[index])
else
return false
}
// test
var a1 = [1,2,3];
var a2 = [1,2,3];
var a3 = ['a', 'r', 'r', 'a', 'y', '1']
var a4 = ['a', 'r', 'r', 'a', 'y', '2']
console.log(compareArrays(a1,a2)) // true
console.log(compareArrays(a1,a3)) // false
console.log(compareArrays(a3,a4)) // false
虽然这只适用于标量数组(请参见下面的注释),但代码很短:
array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})
与上文相同,但在ECMAScript 6/CoffeeScript/TypeScript中使用箭头函数:
array1.length === array2.length && array1.every((value, index) => value === array2[index])
(注意:这里的“scalar”表示可以使用==直接比较的值。因此:数字、字符串、引用对象、引用函数。有关比较运算符的更多信息,请参阅MDN引用)。
更新
根据我在评论中看到的内容,对数组进行排序和比较可能会得到准确的结果:
const array2Sorted = array2.slice().sort();
array1.length === array2.length && array1.slice().sort().every(function(value, index) {
return value === array2Sorted[index];
});
Eg:
array1 = [2,3,1,4];
array2 = [1,2,3,4];
然后上述代码将返回true