Search code examples
arraysswiftloopsswift5

Remove objects at specific indexes from Array in Swift 5


I have an array of dictionaries and another array which contains indexes from which need to be removed from the first array. I tried making them IndexSet and using the removeObjects(at: indexes:IndexSet) but fails. Anyone has any idea how to do this?

print(listArray.count)
print(listToBeRemoved.count)`
let set = NSMutableIndexSet()
for (idx, index) in listToBeRemoved.enumerated(){
     set.add((index as! NSIndexPath).row)
     if idx == listToBeRemoved.count-1{
     listArray.removeObjects(at: set as IndexSet)
}
print(listArray.count)

log prints: 111 24 87 but the problem is that the listArray contains the same object in of all its indexes. Before removing the objects all objects are different as intended.

ListArray is an array of dictionaries where dictionary has 4 keys:

{
    Date = Date();
    Source = String;
    Title = String;
    Url = String;
}

whereas listToBeRemoved is an array of IndexPaths e.g.:

(
"<NSIndexPath: 0xf7e2dd0ccbb6f985> {length = 2, path = 0 - 63}",
"<NSIndexPath: 0xf7e2dd0cc916f985> {length = 2, path = 0 - 42}",
"<NSIndexPath: 0xf7e2dd0cc936f985> {length = 2, path = 0 - 43}",
"<NSIndexPath: 0xf7e2dd0cc9b6f985> {length = 2, path = 0 - 47}",
"<NSIndexPath: 0xf7e2dd0cca56f985> {length = 2, path = 0 - 48}"

)

Any advice? Thanks in advance


Solution

  • What you can do:

    • Get all indices
    • Sort them descending
    • Iterate over the indices, and remove the item at that index

    Why reversed? Because else, imagine you have the indices [0, 1], and your array is [A, B, C] If you start looping on the indices, you'll have : 0: Remove first from [A, B, C] -> [B, C] 1: Remove second from [B, C] -> [B]

    So, if you are using Swift Array:

    let indices = listToBeRemoved.map{ $0.row }.sorted()
    indices.reversed().forEach{ listArray.remove(at: $0) }
    

    Since you are using NSMutableArray (I'd strongly recommend you to avoir NSStuff when Stuff is available): listArray.remove(at: $0) is listArray.removeObject(at: $0)

    Another possible solution:

    let indices = IndexSet(listToBeRemoved.map{ $0.row })
    listArray.removeObjects(at: indices) //Objective-C
    listArray.remove(atOffsets: indices) //Swift