Testing equality of vectors in a 2 dimensional array

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;
}
2 Likes