4

I had a class which is not a subclass of NSObject and an array of instances of that class.

enum ObjectType{
  case type1
  case type2
  case type3  
}

class MyObject {
  var type = ObjectType!
  //some other properties...
}

let array = [obj1(type:type1),
             obj2(type:type2),
             obj3(type:type3),
             obj4(type:type2),
             obj5(type:type3)]

let type2Array = array.filter(){ $0.type == .type2}
// type2Array is supposed to be [obj2, obj4]

this is causing fatal error: array cannot be bridged from Objective-C

How can I filter array appropriately?

Do I have to subclass from NSObject or make my class conform to any protocol?

1
  • Are you using Xcode 7.3? Commented Mar 28, 2016 at 10:49

1 Answer 1

13

From what I can see from your question, none of the above really has any connection to Objective-C. Your example contains a few other issues, however, keeping it from working as intended.

  • MyObject has no initializer (as of Swift 2.2, you should include at least one initializer).
  • What are obj1, obj2, ... ? You treat these as methods or class/structures types, when I presume you're intending for these to be instances of the MyObject type.

If fixing the above, the actual filtering part of your code will work as intended (note that you can omit () from filter() {... }), e.g.:

enum ObjectType{
    case type1
    case type2
    case type3
}

class MyObject {
    var type : ObjectType
    let id: Int
    init(type: ObjectType, id: Int) {
        self.type = type
        self.id = id
    }
}

let array = [MyObject(type: .type1, id: 1),
             MyObject(type: .type2, id: 2),
             MyObject(type: .type3, id: 3),
             MyObject(type: .type2, id: 4),
             MyObject(type: .type3, id: 5)]

let type2Array = array.filter { $0.type == .type2}
type2Array.forEach { print($0.id) } // 2, 4

As an alternative to filtering directly to an enumeration case, you could specify the rawValue type of your enumeration and match to this instead. E.g. using an Int rawValue allows you to (in addition to filtering w.r.t. rawValue) perform pattern matching for say, ranges of cases in your enumeration.

enum ObjectType : Int {
    case type1 = 1  // rawValue = 1
    case type2      // rawValue = 2, implicitly
    case type3      // ...
}

class MyObject {
    var type : ObjectType
    let id: Int
    init(type: ObjectType, id: Int) {
        self.type = type
        self.id = id
    }
}

let array = [MyObject(type: .type1, id: 1),
             MyObject(type: .type2, id: 2),
             MyObject(type: .type3, id: 3),
             MyObject(type: .type2, id: 4),
             MyObject(type: .type3, id: 5)]

/* filter w.r.t. to rawValue */
let type2Array = array.filter { $0.type.rawValue == 2}
type2Array.forEach { print($0.id) } // 2, 4

/* filter using pattern matching, for rawValues in range [1,2],
   <=> filter true for cases .type1 and .type2 */
let type1or2Array = array.filter { 1...2 ~= $0.type.rawValue }
type1or2Array.forEach { print($0.id) } // 1, 2, 4
Sign up to request clarification or add additional context in comments.

1 Comment

Is it required to have init in a custom class? How about let object1 = MyObject; object1.id = 1; object1.type = type1 ...?

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.