Removing multiple indexes from an array in Swift

I have an array and I want to delete a bunch of indexes

var arr = [0,1,2,3,4,5,6] var rmIndices = [1,4,5] 

What is the best way to remove 1,4,5 indices from arr?

+8
swift
source share
6 answers

Instead of a list of indexes to be removed, it may be easier to have a list of indexes that you can use using the Set type:

 let rmIndices = [1,4,5] let keepIndices = Set(arr.indices).subtract([1,4,5]) 

Then you can use PermutationGenerator to create a new array of only those indices:

 arr = Array(PermutationGenerator(elements: arr, indices: keepIndices)) 
+8
source share

Please note that PermutationGenerator leaves in Swift 3, and also does not preserve the order of the same, although it may have happened at the same time. Using the accepted answer results in [2, 6, 0, 3] , which may be unexpected. Several alternative approaches that give the expected result [0, 2, 3, 6] :

 let flatArr = arr.enumerate().flatMap { rmIndices.contains($0.0) ? nil : $0.1 } 

or

 let filterArr = arr.enumerate().filter({ !rmIndices.contains($0.0) }).map { $0.1 } 
+18
source share
 rmIndices.sort({ $1 < $0 }) for index in rmIndices { arr.removeAtIndex(index) } 

Note that I sorted the indexes in descending order. This is because every time you delete an element E, the indices of elements outside E decrease by one.

+5
source share

For Swift 3

  var arr = [0,1,2,3,4,5,6] let rmIndices = [1,4,5] arr = arr.filter{ !rmIndices.contains($0) } print(arr) 

if you want to output very quickly, you can use

  var arr = [0,1,2,3,4,5,6] let rmIndices = [1,4,5] arr = Array(Set(arr).subtracting(rmIndices)) print(array) 

But it will change the order of your array

+1
source share

The problem with a flat map is that it gives incorrect results if your array contains options.

The following is much faster than the proposed functional style options and works with options. You just need to make sure rmIndices sorted and unique. It is also a pretty linguistic agnostic.

  var numRemoved: Int = 0 for index in rmIndices { let indexToRemove = index - numRemoved arr.remove(at: indexToRemove) numRemoved += 1 } 

If you need to make sure rmIndices sorted and unique:

  rmIndices = Set(rmIndices).sorted() 

Using XCTest to remove 500 elements (including an operation to ensure uniqueness and sorting):

0.006 s

against.

arr.enumerated().filter({ !rmIndices.contains($0.0) }).map { $0.1 } :

0.206 s

I use this as an extension for an array

 extension Array { mutating func remove(at indices: [Int]) { let rmIndices = Set(indices).sorted() var numRemoved: Int = 0 for index in rmIndices { let indexToRemove = index - numRemoved self.remove(at: indexToRemove) numRemoved += 1 } } } 
+1
source share

Delete items using an array of indices:

  • Array of strings and indexes

     let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"] let indexAnimals = [0, 3, 4] let arrayRemainingAnimals = animals .enumerated() .filter { !indexAnimals.contains($0.offset) } .map { $0.element } print(arrayRemainingAnimals) //result - ["dogs", "chimps", "cow"] 
  • Array of integers and indices

     var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] let indexesToRemove = [3, 5, 8, 12] numbers = numbers .enumerated() .filter { !indexesToRemove.contains($0.offset) } .map { $0.element } print(numbers) //result - [0, 1, 2, 4, 6, 7, 9, 10, 11] 



Delete elements using element value of another array

  1. Arrays of Integers

     let arrayResult = numbers.filter { element in return !indexesToRemove.contains(element) } print(arrayResult) //result - [0, 1, 2, 4, 6, 7, 9, 10, 11] 
  2. Line arrays

     let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] let arrayRemoveLetters = ["a", "e", "g", "h"] let arrayRemainingLetters = arrayLetters.filter { !arrayRemoveLetters.contains($0) } print(arrayRemainingLetters) //result - ["b", "c", "d", "f", "i"] 
0
source share

All Articles