如何检查对象是否是一个类型的数组之一?

时间:2018-03-08 19:51:44

标签: swift filter contains

给出以下数组:

let ignoredViewControllerTypes:[UIViewController.Type] = [
    ViewControllerB.self,
    ViewControllerC.self
]

let allViewControllers = [
    viewControllerAInstance,
    viewControllerBInstance,
    viewControllerCInstance,
    viewControllerDInstance
]

过滤allViewControllers的语法是什么,以便排除ignoredViewControllerTypes中的那些类型?

我试过这个,但它不起作用:

let filteredControllers = allViewControllers.filter{ !ignoredViewControllerTypes.contains($0.self) }

那么我错过了什么?

2 个答案:

答案 0 :(得分:1)

这应该有效:

let filteredControllers = allViewControllers.filter { viewController in
    !ignoredViewControllerTypes.contains(where: { type(of: viewController) == $0 })
}

答案 1 :(得分:1)

让我们在子任务中细分:

  1. 您想检查是否应该允许控制器

    func isAllowed(_ controller: UIViewController) -> Bool {
        return !ignoredViewControllerTypes.contains { controller.isKind(of:  $0) }
    }
    
  2. 您想要过滤控制器数组:

    let filteredControllers = allViewControllers.filter(isAllowed)
    
  3. 请注意,isAllowed还会过滤忽略的控制器的子类,如果您想要精确的类型匹配,那么您应该使用@ dan的答案。

    作为奖励,因为我喜欢函数式编程,你可以通过将isAllowed转换为高阶函数来使func doesntBelong(to prohibitedClasses: [AnyClass]) -> (AnyObject) -> Bool { return { obj in prohibitedClasses.contains { obj.isKind(of: $0) } } } 成为一个纯粹而灵活的函数:

    let filteredControllers = allViewControllers.filter(doesntBelong(to: ignoredViewControllerTypes))
    

    ,可以这样使用:

    @IBAction func buttonAction(_ sender: Any) {
    
        if let path = Bundle.main.path(forResource: "slipMovement", ofType: 
        "mp4") {
            let video = AVPlayer(url: URL(fileURLWithPath: path))
            let videoPlayer = AVPlayerViewController()
            videoPlayer.player = video
    
            present(videoPlayer, animated: true, completion:  {
                video.play()
            })
        }
    }