【问题标题】:How can you check if an object is one of an array of types?你如何检查一个对象是否是一个类型数组中的一个?
【发布时间】:2018-08-17 07:03:35
【问题描述】:

给定以下数组:

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

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

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

这个我试过了,还是不行:

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

那么我错过了什么?

【问题讨论】:

    标签: swift filter contains


    【解决方案1】:

    这应该可行:

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

    【讨论】:

      【解决方案2】:

      让我们把它分解成子任务:

      1. 你想检查一个控制器是否应该被允许

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

        let filteredControllers = allViewControllers.filter(isAllowed)
        

      注意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))
      

      【讨论】:

      • 这真的很酷(即你的功能部分。)不熟悉双箭头语法。你能详细说明一下吗?
      • 等等!我得到了它!它返回一个'(AnyObject) -> Bool' 的闭包。
      • @MarqueIV 是的,你没看错,语法表明doesntBelong(to:) 返回一个以对象为参数并返回Bool 的函数。你可以把它想象成一个“函数工厂”。
      猜你喜欢
      • 2023-01-13
      • 2010-10-20
      • 2017-07-26
      • 2018-10-16
      • 2012-05-07
      • 2011-06-02
      • 1970-01-01
      • 2022-10-01
      相关资源
      最近更新 更多