Ad

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

Ad

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
  })
})
Ad
source: stackoverflow.com
Ad