1

What is best way in swift to get objects of specific type. e.g

protocol Fruit {
    func setColor()

}

class Orange:NSObject, Fruit {
    func setColor() {

    }
}

class Apple:NSObject, Fruit {
    func setColor() {
    }
}


class MyClass {

    var fruits:[Fruit]? // get from data base

    //here how to get fruits only of type Orange. i.e. Array of oranges

}

Here one way is I can put "for in" loop and check type of each object and then can add it in new array.

But is there any other swifty way to do?

EDIT:

Below works for me. Is there any other way to do?

  var oranges: [Orange] = []
   for orange in fruits {

   if let myOrange = orange as? Orange {
        oranges.append(myOrange)
     }
   }
5
  • 1
    It's bad practice to write setters and getters in Swift. Just use public properties. That's what they're there for. Commented Feb 1, 2017 at 4:04
  • 1
    Also no need to subclass NSObject unless you are planning to conform it to NSCoding otherwise you should use structs instead of classes. Commented Feb 1, 2017 at 4:54
  • 1
    bad naming for the loop, would be much better for fruit in fruits and then if let orange = fruit as? Orange { Commented Feb 1, 2017 at 5:02
  • btw just add a computed property to MyClass var oranges: [Orange] { return fruits.flatMap{$0 as? Orange} } Commented Feb 1, 2017 at 5:11
  • 1
    Java is bad for a reason... setters and getters make NO SENSE 99% of the time... it's just extra work for you so you have the feeling of 'encapsulation safety' but really it's not doing a thing for your code! Commented Feb 1, 2017 at 6:49

1 Answer 1

2

If you simply want to iterate over these in a for loop, just add a where clause:

for fruit in fruits where fruit is Orange {

}

If you want a filtered array (still of type [Fruit]) to store for future use, use filter:

let oranges = fruits.filter{ $0 is Orange }

If you want a filtere array (of type [Orange]) to store for future use, user flatMap:

let oranges = fruits.flatMap{ $0 as? Orange }
Sign up to request clarification or add additional context in comments.

5 Comments

I am getting error for filter option - Cannot convert value of type '[Fruit]' to expected argument type '[Orange]'
@user364765 Did you unwrap fruits?
let oranges = fruits.flatMap { $0 as? Orange }
@user3647675 Oh yeah, if you want to get an [Orange] back, you'll need to actually do the cast, as vacawama suggests.
@user3647675 can you update your code now to show the new error and such?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.