Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate NSSet and cast to type in one step

Tags:

swift

Is there a way to cast elements from a NSSet (or any non-native Swift collection) and cast each element to a type in one step. Currently I'm doing this

// "zoo" is an NSOrderedSet
for animal in zoo {
  if let animal = animal as? Animal {
    if animal.needFeeding {
      // Feed the animal
    }
  }
}

the above seems a bit clumsy. The set is coming from CoreData so I have to use NSSet.

like image 556
Friedrich 'Fred' Clausen Avatar asked Apr 30 '16 11:04

Friedrich 'Fred' Clausen


3 Answers

You can use pattern matching case let in a for loop:

for case let animal as Animal in zoo  {
    if animal.needFeeding {

    }
}

Note that this will just skip elements which are not instances of (a subclass of) Animal.

like image 186
Martin R Avatar answered Oct 21 '22 13:10

Martin R


Just for completeness, NSOrderedSet is just a combination of a set and an array, you could use either one of them for iterating, casting it to the Swift Set or Array type:

for animal in zoo.set as! Set<Animal> {
    if animal.needFeeding {
    }
}

or

for animal in zoo.array as! [Animal] {
    if animal.needFeeding {
    }
}
like image 26
Sulthan Avatar answered Oct 21 '22 14:10

Sulthan


For NSOrderedSet and the like, I would safely loop over mapped content like this:

for animal in zoo.flatMap({ $0 as? Animal }) {
    if animal.needFeeding {
        // Feed the animal
    }
}

Ah, of course, there's a similar Q&A... and I already answered something similar. More alternatives in the other one, though: https://stackoverflow.com/a/35558210/2227743

like image 2
Eric Aya Avatar answered Oct 21 '22 12:10

Eric Aya