我已经建立了自己的阵列平等''''''''函数,当数组中的所有值都是唯一的时,它按预期工作:
示例: (工作)
var
a = [1, 2, 3, ["a", "b"]],
b = [1, 2, 3, ["a", "b"]];
arrayEquals(a, b); /* returns: [true, true, true, [true, true]] */
但是,如果存在重复值,则最终结果会严重损坏:
示例: (非工作)
在此示例中, 1
在第一个数组中存在两次。问题是第二个 1
会返回第二个数组的第一个 1
作为匹配,即使 {{ 1}} 已经在第一个数组的前一个 1
之前就已经匹配了。
1
问题:
有没有办法安全地删除或避免检查匹配的元素,以便更改结果?
我尝试过的事情:
1)我试图以下面的方式删除两个阵列中存在的元素,但不幸的是它没有任何好处:
示例:
var
a = [1, 1, 2],
b = [1, 2, 2];
arrayEquals(a, b); /* returns: [true, false, false] */
/* should return: [true, false, true] */
2)我已经尝试过 if (eachA === eachB) {
a.splice.call(index, 1); // Removing the matched elements
b.splice.call(jindex, 1); // Removing the matched elements
result[index] = true;
}
以及 if (eachA === eachB && !result[index] && !result[jindex]) result[index] = true;
和< strong> result[index]
已经为真,这意味着一个数组中的值已与另一个数组中的值匹配。
代码:
result[jindex]
&#13;
检查程序:
/* Main function */
function arrayEquals(a, b, result) {
return (a === b && a !== null) || (a.length === b.length &&
(function check(a, b, result) {
/* Check equality between 'a' and 'b' arrays */
a.forEach(function(eachA, index) {
b.forEach(function(eachB, jindex) {
if (eachA === eachB) result[index] = true;
/* Handle objects */
else if (isObject(eachA) && isObject(eachB))
result[index] = objectEquals(a, b);
/* Handle arrays */
else if (isArray(eachA) && isArray(eachB))
check(eachA, eachB, (result[index] = []));
/* Turn all 'undefined' to 'false' */
else result[index] = (!!result[index]) ? true : false;
});
});
return result;
})(a, b, (result = [])));
}
/* Usage */
var
a = [1, 1, 2, ["a", "b"]],
b = [1, 2, 2, ["a", "b"]];
console.log(arrayEquals(a, b)); /* returns: [true, true, true, [true, true]] */
/* should return: [true, false, true, [true, true]] */
/* Supplementary functions */
function isArray(array) {return !!array && array.constructor === Array;}
function isObject(object) {return !!object && object.constructor === Object;}
对于第一个数组的每个索引,我们检查第二个数组的所有索引,逐个找到匹配。
对于第一个数组, var
a = [1, 1, 2],
b = [1, 2, 2];
(在索引0处)与 1
(在索引0处)第二个数组。
然后对于第一个数组, 1
(在索引1处)与第二个数组的任何索引都不匹配(索引0处的1不算数,因为我们之前找到了匹配项)。
最后,对于第一个数组, 1
(在索引2处)匹配 2
第二个数组的(在索引1处)。结果:[true,false,true] | 不等于。
要点:
每个索引必须匹配,可能是相同的索引或其他索引。
如果第二个数组的一个索引用作第一个数组的先前索引的匹配项,则不能再将其用作匹配项。
必须在另一个要使用的索引处再次存在相同的元素。
答案 0 :(得分:1)
如果保证您的阵列具有相同的结构,您可以执行以下操作;
var a = [1, 1, 2, ["a", "b"]],
b = [1, 2, 2, ["a", "b"]];
function arrayCompare(a,b){
return a.map((e,i) => Array.isArray(e) ? arrayCompare(e, b[i])
: e === b[i]);
}
console.log(arrayCompare(a,b))
&#13;
答案 1 :(得分:0)
两个数组应具有相同的长度和完全相同的元素 在任何顺序中。
您可以使用返回数组的Array.prototype.filter()
,.length
var a = [1, 1, 2],
b = [1, 2, 2],
c = [1, 2, 1],
d = [2, 1, 3],
e = [2, 2, 1],
f = [2, 1, 2];
var compare = (a, b) =>
a.map(el =>
b.filter(item => item === el).length ===
a.filter(item => item === el).length
);
console.log(compare(a, b), compare(c, d), compare(e, f))
&#13;
答案 2 :(得分:0)
而不是两个foreach循环只使用一个并与其他元素的相同索引进行比较。请查看下面的代码段。
/* Main function */
function arrayEquals(a, b, result) {
return (a === b && a !== null) || (a.length === b.length &&
(function check(a, b, result) {
/* Check equality between 'a' and 'b' arrays */
a.forEach(function(eachA, index) {
if (eachA === b[index]) result[index] = true;
/* Handle objects */
else if (isObject(eachA) && isObject(b[index]))
result[index] = objectEquals(a, b);
/* Handle arrays */
else if (isArray(eachA) && isArray( b[index]))
check(eachA, b[index], (result[index] = []));
/* Turn all 'undefined' to 'false' */
else result[index] = (!!result[index]) ? true : false;
});
return result;
})(a, b, (result = [])));
}
/* Usage */
var
a = [1, 1, 2, ["a", "b"]],
b = [1, 2, 2, ["a", "b"]];
console.log(arrayEquals(a, b)); /* returns: [true, true, true, [true, true]] */
/* should return: [true, false, true, [true, true]] */
/* Supplementary functions */
function isArray(array) {return !!array && array.constructor === Array;}
function isObject(object) {return !!object && object.constructor === Object;}
&#13;
答案 3 :(得分:0)
这应该有用......
var
a = [1, 2, 3, ["a", "b"]],
b = [1, 2, 3, ["a", "b"]];
var
c = [1, 1, 2, ["a", "b"]],
d = [1, 2, 2, ["a", "b"]];
function arrayEquals(a, b) {
if (a.length !== b.length) return false
return a.map(function(el, i) {
if (typeof a[i] === 'object' && a[i] instanceof Array) return arrayEquals(a[i], b[i])
return a[i] === b[i] ? true : false
})
}
console.log(arrayEquals(a, b))
console.log(arrayEquals(c, d))
&#13;
答案 4 :(得分:0)
你太复杂了。您只需要map
最长的数组,并且对于每个索引,比较两个元素(如果有的话)是否为数组。如果是,则使用递归,否则正常比较。
function arrayCompare(arr1, arr2) {
if(arr1.length < arr2.length) return arrayCompare(arr2, arr1);
return arr1.map(function(item, idx) {
if (idx >= arr2.length) return false;
var b = Array.isArray(item) && Array.isArray(arr2[idx]);
return (b ? arrayCompare : Object.is)(item, arr2[idx]);
});
}
console.log(JSON.stringify(arrayCompare([1, 2, 3, ["a", "b"]], [1, 2, 3, ["a", "b"]])));
console.log(JSON.stringify(arrayCompare([1, 1, 2, ["a", "b"]], [1, 2, 2, ["a", "b"]])));
console.log(JSON.stringify(arrayCompare([1, 1, 2, 3], [1, 2, 2, ["a", "b"]])));
console.log(JSON.stringify(arrayCompare([1], [1, 2, 2, ["a", "b"]])));
答案 5 :(得分:0)
这是一个完全递归的函数,用于比较数组:
select cast(orig_time as time(0))
答案 6 :(得分:0)
也许,有比以下更好的方法,但以下仍然可以完成工作。
解决方案的作用:
基本上,以下操作是将 eachA
和 eachB
的值(如果它们相等)更改为某些正则表达式
据我所知,两个正则表达式不能相等,所以在其中一个数组中已经存在相同正则表达式的狂野场景中,它会导致 false
无论如何。
毕竟谁把一个RegExp放在一个数组中并且碰巧想检查那个数组是否等于另一个?!
<强>解决方案:强>
if (eachA === eachB) {
result[index] = true;
a[index] = b[jindex] = /RegExp/;
}
此外:
为了避免任何意外,必须打破内部 forEach
循环,以便在找到匹配项时,它会直接转到下一个字符。因此,我们将 forEch
**更改为** for
,然后将其分解。
if (eachA === eachB) {
result[index] = true;
a[index] = b[jindex] = /RegExp/;
break;
}
<强>代码:强>
/* Main function */
function arrayEquals(a, b, result) {
return (a === b && a !== null) || (a.length === b.length &&
(function check(a, b, result) {
/* Check equality between 'a' and 'b' arrays */
a.forEach(function(eachA, index) {
for (var jindex = 0, eachB = b[jindex]; jindex < b.length;
jindex++, eachB = b[jindex]) {
if (eachA === eachB) result[index] = true,
a[index] = b[jindex] = /RegExp/, break;
}
/* Handle objects */
else if (isObject(eachA) && isObject(eachB))
result[index] = objectEquals(a, b);
/* Handle arrays */
else if (isArray(eachA) && isArray(eachB))
check(eachA, eachB, (result[index] = []));
/* Turn all 'undefined' to 'false' */
else result[index] = (!!result[index]) ? true : false;
}
});
return result;
})(a, b, (result = [])));
}
/* Usage */
var
a = [1, 2, 2, ["a", "b"]],
b = [1, 2, 2, ["a", "b"]];
console.log(JSON.stringify(arrayEquals(a, b)));
/* Supplementary functions */
function isArray(array) {return !!array && array.constructor === Array;}
function isObject(object) {return !!object && object.constructor === Object;}
&#13;
答案 7 :(得分:0)
我正在做C#和C ++,而不是JavaScript,所以我不能给你工作代码。但是这里有一些pseudecode可以让你知道它是如何工作的 这是写在我的脑海里,用手机打字(糟糕的工作)和未经测试。希望这对你有用!请为任何拼写错误道歉,这可能是德国自动更正造成的。
bool Compare (array a, array b, ref array result)
{
Check whether arrays existiert and length is equal, return false if not;
array<bool> b_used = new array(length (b));
for (int indexa = 0 to length(a)-1)
{
if (a is value or object)
{ // compare against every b
result[indexa] = false;
for (int indexb = 0 to length(b)-1)
{
if (b_used[indexb])
continue; // this is the key: don't use an index twice!
if (a[indexa] == b[indexb])
{
result[indexa] = true;
b_used[indexb] = true;
break;
}
}
}
Else if (array)
...
And so on.
请注意,内部数组是单独处理的,不与外部数组的值进行比较。