In Swift how can I filter an array of objects conf

2019-05-01 16:25发布

I have a protocol, 'VariousThings', and two classes which conform to it, 'ThingType1' and 'ThingType2'. I've put some objects of these two types of classes into an array containing 'VariousThings'. I now want to just take all the objects out of that array that are of class type 'ThingType2' for example. How can I do this?

Here's what I have so far:

protocol VariousThings: class {

}

class ThingType1: VariousThings {

}

class ThingType2: VariousThings {

}


let array: [VariousThings] = [ThingType1(), ThingType2()]


func itemsMatchingType(type: VariousThings.Type) -> [VariousThings] {
    return array.filter { variousThing in
        return (variousThing.self === type)
    }
}


let justThingTypes1: [VariousThings] = itemsMatchingType(ThingType1)

4条回答
对你真心纯属浪费
2楼-- · 2019-05-01 17:00

You could use a generic

func itemsMatchingType<T : VariousThings>(type: T.Type) -> [VariousThings] {
  return array.filter { $0 is T }
}
查看更多
别忘想泡老子
3楼-- · 2019-05-01 17:00
let justThingTypes1: [VariousThings] = array.filter {
  variousThing in
  return Mirror(reflecting: variousThing).subjectType == ThingType1.self
}
查看更多
相关推荐>>
4楼-- · 2019-05-01 17:10

I would use compactMap instead of filter here in order to give you better type safety. You can use a conditional downcast to filter out the elements you want and generics in order to preserve type information. This takes advantage of the fact that compactMap can filter out nil results from the transform function.

let array: [VariousThings] = [ThingType1(), ThingType2()]    

func itemsMatchingType<T : VariousThings>(_ type: T.Type) -> [T] {
  return array.compactMap { $0 as? T }
}

let justThingTypes1 = itemsMatchingType(ThingType1.self) // of type [ThingType1]

Now the array you get out of your itemsMatchingType function is [ThingType1] if you pass in ThingType1, rather than simply [VariousThings]. That way you don't have to deal with ugly forced downcasts later down the line.

查看更多
我想做一个坏孩纸
5楼-- · 2019-05-01 17:12

You can use the filter for this:

let justThingsTypes1 = array.filter { $0 is ThingType1 }
查看更多
登录 后发表回答