Basically we shouldn’t use method Array::includes() to compare objects.
B/c object comparison in JS doesn’t check their contents (properties & their values).
Instead such comparison action merely checks whether both memory addresses match:
'use strict';
function setup() {
noCanvas();
const vec = createVector(), arr = [ vec ];
print(arr.includes(vec)); // true
print(arr.includes(createVector())); // false
print(arr[0] == vec, arr[0] == createVector()) // true, false
print(createVector() == createVector()); // false
print(createVector().x == createVector().x); // true
}
That actually makes the algorithm slightly more complex.
Just coded a double function which relies on method Array::some() for a customized object comparison:
The idea is to clone the 2nd vector array row and then invoke Array::some() inside the 1st vector array row’s loop.
Inside Array::some()'s callback we use method p5.Vector.equals() to check whether the contents of both vectors match.
Every time both vectors match we Array::splice() that vector outta the cloned 2nd vector array row:
Otherwise, if Array::some() fails to find a match, we break
from the loop.
That function returns true
only if the cloned 2nd vector array row becomes empty:
'use strict';
function setup() {
noCanvas();
const
row = [
createVector(PI, TAU),
createVector(),
createVector(RAD_TO_DEG, DEG_TO_RAD, Math.SQRT2),
createVector(PI, TAU)
],
equal = [
createVector(RAD_TO_DEG, DEG_TO_RAD, Math.SQRT2),
createVector(PI, TAU),
createVector(PI, TAU),
createVector()
],
diff = [
createVector(RAD_TO_DEG, DEG_TO_RAD, Math.SQRT2),
createVector(PI, TAU),
createVector(TAU, PI),
createVector()
],
same = [
createVector(PI, TAU),
createVector(PI, TAU),
createVector(PI, TAU),
createVector(PI, TAU)
];
print(rowsContainSameVecs(row, equal)); // true
print(rowsContainSameVecs(row, diff)); // false
print(rowsContainSameVecs(row, row)); // true
print(rowsContainSameVecs(equal, row)); // true
print(rowsContainSameVecs(equal, diff)); // false
print(rowsContainSameVecs(row, same)); // false
print(rowsContainSameVecs(same, row)); // false
}
function rowsContainSameVecs(vecRowOne, vecRowTwo) {
if (vecRowOne?.length != vecRowTwo?.length) return false;
vecRowTwo = vecRowTwo.slice();
for (const vecOne of vecRowOne)
if (!vecRowTwo.some(removeIfSameVec, vecOne)) break;
return !vecRowTwo.length;
}
function removeIfSameVec(vec, idx, arr) {
const same = vec.equals(this);
same && arr.splice(idx, 1);
return same;
}