0

I'm trying to check for array equality using forEach in JavaScript. This criteria is key, and the answer is not on Stack Overflow already.

The tests that are checking equality and expecting true are failing. I have a feeling I'm running into an issue to do with scope. Can someone please walk me through it?

function eql(arr1, arr2) {
  
  arr1.forEach((el) => {
    if (arr1[el] === arr2[el]) {
      return true;
    } 
  })
  return false
}

Here are the test results I want to change:

eql([], [])

Expected: true but got: false

eql(['a', 'b'], ['a', 'b'])

Expected: true but got: false
dereknahman
  • 87
  • 1
  • 9
  • 1
    please add some examples. and results. btw, `forEach` does not return a result from an inner return. – Nina Scholz Sep 29 '20 at 07:33
  • 1
    `return true` within the callback doesn't do anything. It is returning *from the callback` not from `eql`. You either need to convert to using a conventional loop, change it so the result is outside the callback and only changed within, or change to `.some()`/`.every()` and return the result of that. – VLAZ Sep 29 '20 at 07:34
  • `el` is not the index, it's each array item. – adiga Sep 29 '20 at 07:34
  • `return true` on the first match (if it would work, see comments above) doesn't tell you if all elements are equal. – Andreas Sep 29 '20 at 07:35
  • you can use `every`, something like this: `arr1.every((e,i)=>e===arr2[i])` – gorak Sep 29 '20 at 07:37
  • 1
    @gorak `every` and most array methods skip holes. So, it will return true for `[,,3]` and `[1,2,3]` – adiga Sep 29 '20 at 07:42

2 Answers2

1

There are a number of things wrong with your code

  • forEach doesnt return anything, it just iterates over the items performing some task
  • even if forEach did return something you're not returning the result from your method!
  • el is the element itself, not its index
  • returning true from inside the method passed to forEach does not return from the eql method itself. Your method will always return false.
  • ... but even if that worked, returning true on the first match will not tell you the entire array equals

Your code can be shortened to

function eql(arr1, arr2) {
    return arr1.length == arr2.length && arr1.every( (x,i) => x == arr2[i]);
}

console.log(eql([],[]));
console.log(eql([1,2,3],[1,2,3]));
console.log(eql([1,2,3],[1,2,2]));
console.log(eql([1,2,3],[1,2,3,4]));
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • `eql([,,3],[1,2,3])` returns `true` because `every` skips holes. – adiga Sep 29 '20 at 07:39
  • 1
    @adiga interesting, didnt know that. I suspect not so much of a problem in day to day use, but could be a gotcha somewhere down the road. – Jamiec Sep 29 '20 at 07:41
  • OP asks for a solution with `forEach` and then states that "this criteria is key". I agree with your solution, but it doesn't seem to fully fit the question… – Barthy Sep 29 '20 at 08:01
  • 1
    @Barthy that line was added after this answer was posted. I'll leave it here for future visitors who might not have that requirement – Jamiec Sep 29 '20 at 08:26
1

This can be one of the many solutions

function eql(arr1, arr2) {
  let returnStatement = true;

  if (arr1.length !== arr2.length) {
    returnStatement = false;
  } else if (returnStatement) {
    arr1.forEach((el, index) => {
      if (el !== arr2[index]) {
        returnStatement = false;
      }
    });
  }

  return returnStatement;
}

console.log(eql([1, 2, 4], [1, 2, 4]))
adiga
  • 34,372
  • 9
  • 61
  • 83
Ahmad Suddle
  • 190
  • 7