原始主题,我知道,但任何人都可以评论以下算法来比较两个ES5 arrrays:
function equal_arrays(a, b) {
"use strict";
var c = 0;
return a.every(function (e) {
return e === b[c++];
});
}
我认为这是非常干净且明显地使用[] .every()来快速比较两个数组? 我有那种唠叨“肯定不会那么简单吗?”感觉呢?
注意:当两个数组包含严格相同的相同位置的所有元素时,它们是相等的。因此,元素索引和元素值必须完全相等。不同类型的值被认为是不相等的。稀疏阵列也进行了比较。
测试案例:
equal_arrays([],[]) ; // => true
equal_arrays([1,2],[1,2]) ; // => true
equal_arrays([1,,2],[1,,2]) ; // => true
equal_arrays([,],[,]); // => true
equal_arrays([1,,3,,,],[1,,3,,,]); // => true
使用案例yielding =>是的,人们可以想象自己。比较非数组是语法错误。
非常感谢良好的意义和有用的贡献者。似乎“最好的”(从来没有这样的事情)实现是这样的:
function has(element, index)
{
return this[index] === element;
}
function equal_arrays(a, b)
{
return (a.length === b.length) && a.every(has, b) && b.every(has, a);
}
@ tom的双向every()的实现,这是必要的sp,像这样的测试用例工作:
equal_arrays([1,,3],[1,2,3]); //=> false
再次感谢...
答案 0 :(得分:4)
不,它无效。来自MDN docs:
仅对已分配值的数组的索引调用
callback
;对于已删除或从未分配过值的索引,不会调用它。
因此,如果第一个数组有“间隙”,则会跳过它们。
equal_arrays([1, 2, , 4], [1, 2, 4]); // true
equal_arrays([1, 2, 4], [1, 2, , 4]); // false
这是一个更好的实现:
function equal_arrays(a, b) {
if (a.length != b.length) return false;
var i;
for (i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
这是@ RobG的双向every()
想法的优雅实现:
function has(element, index)
{
return this[index] === element;
}
function equal_arrays(a, b)
{
return (a.length === b.length) && a.every(has, b) && b.every(has, a);
}
答案 1 :(得分:3)
我有那种唠叨“肯定不会那么简单吗?”感觉呢?
不,不是。在一个阵列上使用每个将为那个阵列的每个成员测试它,而不是另一个。你必须测试两种方式。
此外,这取决于您的“平等”标准。您可能希望同一索引的每个成员具有相同的值,但您可能不关心顺序,因此[1,2]
等于[2,1]
?并且[,,,2]
等于[2]
?
此外,[1,,2]
应该等于[1,undefined,2]
,即不存在的成员是否应该与具有undefined
值的成员“相等”?
以下可能会完成这项工作。它比较两种方式,检查自己的属性和值。我认为它涵盖了所有情况,但我愿意相信。作为一个单独的函数可能会更好,但添加到Array.prototype很方便。
// Test that own properties of two arrays have the same values
Array.prototype.isEqualTo = function(a) {
var visited = {};
if (this.length != a.length) return false;
// Test every own property of this, remember tested properties
for (var p in this) {
if (this.hasOwnProperty(p)) {
visited[p] = p;
if (!(a.hasOwnProperty(p)) || this[p] !== a[p]) {
return false;
}
}
}
// Reverse test that comparison array only has tested properties
for (var q in a) {
if (a.hasOwnProperty(q) && !(q in this)) {
return false;
}
}
return true;
}
console.log([1,,2].isEqualTo([1,undefined,2])); // false, not defined != undefined
console.log([1,,2].isEqualTo([1,2])); // false, different length
console.log([1,2].isEqualTo([1,2])); // true
请注意,应该忽略继承的属性,就好像比较来自不同窗口的数组(例如,一个来自框架),然后继承的属性将不相等。
答案 2 :(得分:2)
作为替代方案,如果您只想检查两个阵列是否完全相同,您可以这样做:
var a = [1,2,3,4];
var b = [1,2,3,4];
JSON.stringify(a) == JSON.stringify(b); //= true
这应该适用于数字和字符串数组。
答案 3 :(得分:2)
正如CrazyTrain所说,增量值是无用的,你需要首先检查长度:
function equalArrays( a, b ) {
"use strict";
if (a.length !== b.length) return false;
return a.filter(function(el){ return el;}).every(function(e, i) {
return e === b[i];
});
}
是一种有效的算法,可以按值比较数组。