Reputation: 119
I am trying to filter an array A while slicing an array B using the index in the callback function filter.
const endResult = answers[user].filter((ans, index) => {
if (ans !== '') {
return true
} else {
console.log(index)
outsideArray.splice(index, 1)
return false
}
})
It seems I can't use the index inside the filter callback function to splice another array. Is there a way to do this? I tried various things like map() without much success.
outsideArray: Array [ 1, 2, 4, 5 ]
answer[users]: Array [ "fff", "", "", "fffffff", "", "" ]
In the end, I get:
outsideArray: Array [ 1, 4 ]
answer[users]: Array [ "fff", "fffffff" ]
I should get:
outsideArray: Array [ ]
answer[users]: Array [ "fff", "fffffff" ]
Upvotes: 0
Views: 119
Reputation: 2635
You don't actually want to splice
the exactly corresponding indices in your outsideArray
; you want to remove values that match certain indices in answer[users]
. Try this:
outsideArray.splice(outsideArray.indexOf(index), 1)
For example, in the second iteration of the filter call, we have the following:
index
is 1
outsideArray
is [ 1, 2, 4, 5 ]
Now, if you splice outsideArray
at index 1
, you'll get [ 1, 4, 5 ]
. This is not that you want. You want to splice outsideArray
at the index whose value is 1
. That's where indexOf
comes in:
outsideArray.indexOf(index)
returns the first index in outsideArray
where the value is equal to 1
. This is at index 0
.If we splice outsideArray
at index 0
, we get what we want: [ 2, 4, 5 ]
.
Depending on your use case, there are definitely more efficient ways to design this. Currently, you're searching the entirety of outsideArray
in every iteration of the filter
call.
Upvotes: 1
Reputation: 1950
When you use the index directly to remove elements from the outside array, you are referring to the index in the outside array, not the value of each element, which is what it seems you are wanting.
outsideArray: Array [ 1, 2, 4, 5 ]
(Indices are: 0 1 2 3)
So when you remove at index 1
, you remove the item with value 2
. The array is now:
outsideArray: Array [ 1, 4, 5 ]
(Indices are: 0 1 2)
When you remove at index 2
, you remove the item with value 5
. The new array is:
outsideArray: Array [ 1, 4 ]
(Indices are: 0 1)
Now you remove at indices 4
and 5
, but those items don't exists so it doesn't do anything.
What you seem to actually want is to remove the items by value. You can do this by searching the array for the item that matches the value of the index, like so:
outsideArray.splice(outsideArray.indexOf(index), 1)
Upvotes: 1
Reputation: 4636
if you want to delete your array element in increasing order of index, you have to remove the first element each time you get an empty string.
const endResult = answers[user].filter((ans, index) => {
if (ans !== '') {
return true
} else {
outsideArray.splice(0, 1) // or outsideArray.shift()
return false
}
})
If in case you want your indexes to control what to delete from the array you would have to check for your callback's index and array's index match
const endResult = answers[user].filter((ans, index) => {
const outsideArrayIndex = outsideArray.indexOf(index);
if (outsideArrayIndex > -1) {
outsideArray.splice(outsideArrayIndex,1);
return false;
}
return true;
})
Upvotes: 1