Skip to content
Advertisement

Convert these nested functions from arrow to old style and what happens with variables

I’m trying to find items from one list that are not in items in a second list. Almost by dumb luck I got it to work, but only with arrow functions. For me normal functions are easier to read so I tried converting it and the result isn’t what I expect.

data:

const arr1 = [
    {
        "key": 1,
        "val": "one"
    },
    {
        "key": 2,
        "val": "two"
    },
    {
        "key": 3,
        "val": "three"
    }
]

const arr2 = [
    {
        "key": 3,
        "val": "three"
    },
    {
        "key": 4,
        "val": "four"
    },
    {
        "key": 1,
        "val": "one"
    }
]

version 1

arr1.filter((element) => arr2.findIndex((innerElement) => element.key === innerElement.key) === -1); 
// produces object with key 2

version 2

arr1.filter(function(element) { 
    return arr2.findIndex(function(innerElement) { 
      element.key === innerElement.key === -1
    })
}) // produces all three objects in arr1

To make the correct one more terse I removed extra parentheses and it still works:

arr1.filter(element => arr2.findIndex(innerElement => element.key === innerElement.key) === -1);

I’m missing a key aspect here. I get that each item in arr1 is passed to a function and that inner function in turn passes its result to another function and the expression has access to both sets of arguments and gets executed. But I think I have the wrong mental model about the order or something.

Can someone explain what is happening in each step and how to think about it? And how do I make it into a normal function?

I’ll be dealing with a lot of nested structures and I feel this is a weak area that I’d like to get better in.

Thank you

Advertisement

Answer

You need to return the value of the comparison. And the === -1 test must be with the result of findIndex(), not inside its callback.

arr1.filter(function(element) { 
    return arr2.findIndex(function(innerElement) { 
      return element.key === innerElement.key;
    }) === -1;
});

This can be simplified with the some() method.

arr1.filter(function(element) {
  return !arr2.some(function(innerElement) {
    return element.key === innerElement.key
  })
})
Advertisement