henry
henry

Reputation: 119

Filtering an array while slicing another array in the filter callback function in Javascript

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

Answers (3)

ethan.roday
ethan.roday

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

Eric Ferreira
Eric Ferreira

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

Prasanna
Prasanna

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

Related Questions