I've built my own ''array equality'' function and when all values in an array are unique it works as expected:
Example: (working)
var
a = [1, 2, 3, ["a", "b"]],
b = [1, 2, 3, ["a", "b"]];
arrayEquals(a, b); /* returns: [true, true, true, [true, true]] */
When there are duplicate values, however, the final result is damaged heavily:
Example: (non-working)
In this example, 1 exists twice in the first array. The problem is that the second 1 will return the first 1 of the second array as its match, even though that 1 has been already matched right a step ago by the previous 1 of the first array.
var
a = [1, 1, 2],
b = [1, 2, 2];
arrayEquals(a, b); /* returns: [true, false, false] */
/* should return: [true, false, true] */
Question:
Is there a way to safely remove or avoid checking the elements that were matched so that the result is altered?
What I've tried:
1) I have tried removing the elements that are found to exist in both arrays in the way that follows, but unfortunately it doesn't do any good:
Example:
if (eachA === eachB) {
a.splice.call(index, 1); // Removing the matched elements
b.splice.call(jindex, 1); // Removing the matched elements
result[index] = true;
}
2) I've tried if (eachA === eachB && !result[index] && !result[jindex]) result[index] = true; as well thinking that, if result[index] and result[jindex] are already true, it means that a value in one array has been matched to a value in the other.
Code:
/* 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;}
Checking Procedure:
var
a = [1, 1, 2],
b = [1, 2, 2];
For every index of the first array, we check all indices of the second array to one-by-one find a match.
For the first array,
1(at index 0) matches1(at index 0) of the second array.Then for the first array,
1(at index 1) doesn't match any of the indices of the second array (1 at index 0 doesn't count, because we found a match earlier).Lastly, for the first array,
2(at index 2) matches2(at index 1) of the second array. RESULT: [true, false, true] | not equal.
Summary:
Each index must have a match, maybe the same index or some other.
If one index of the second array is used as a match for a previous index of the first array, it cannot be used as a match again.
The same element must exist again at another index to be used.

a[index]is same as element atb[index]?a=[1, 2, 3] | b=[1, 2, 3]ora=[1, 3, 2] | b=[3, 2, 1]. The arrays are not sorted in any way.bcontains all elements of arraya? At any index?