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
CodePudding user response:
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
})
})