0

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

snksnk
  • 1,566
  • 4
  • 21
  • 46
  • Can you show what `listArray` and `listToBeRemoved` are? It would make debugging easier – aheze Nov 18 '20 at 20:11
  • 3
    `let indices = listToBeRemoved.map{ $0.row }.sorted(); indices.reversed().forEach{ listArray.remove(at: $0) }` ? – Larme Nov 18 '20 at 20:20
  • @aheze edited my question. thanks – snksnk Nov 18 '20 at 20:21
  • @Larme Already tried that before... seems to break my dictionaries and still produces multiple same objects – snksnk Nov 18 '20 at 20:28
  • It shouldn't break anything. But does `listToBeRemoved` contains duplicates values. If so, that needs to be fixed with `let indices = Array(Set(listToBeRemoved.map{ $0.row })).sorted()`. – Larme Nov 18 '20 at 20:30
  • @Larme no, its does not contain duplicates. This is the log after your suggestion (let indices = listToBeRemoved.map{ ($0 as AnyObject).row }.sorted()ndices.reversed().forEach{ listArray.remove($0) } print(listArray.count) 112 24 112. So it does not remove the objects.. – snksnk Nov 18 '20 at 20:37
  • remove(at:), not remove(). – Larme Nov 18 '20 at 20:40
  • And why do you use what I guess be NSArray and NSDictionary ? Use Swift equivalent native – Larme Nov 18 '20 at 20:41
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/224751/discussion-between-snksnk-and-larme). – snksnk Nov 18 '20 at 20:45
  • Related: https://stackoverflow.com/questions/26173565/removeobjectsatindexes-for-swift-arrays/50835467#50835467 – vadian Nov 18 '20 at 21:15

1 Answers1

1

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(attOffsets: indices) //Swift
Larme
  • 24,190
  • 6
  • 51
  • 81