按具有关联值的枚举 属性 过滤项目数组

Filter array of items by enum property with associated value

class MyClass: Decodable {

    let title: String?
    let type: MyClass.MyType?

    enum MyType {
        case article(data: [Article])
        case link(data: [LinkTile])
        case none
    }
}

我想过滤 MyClass 项的数组,因此过滤后的数组将不包含类型为 .none

的实例
let filteredArray = array.filter { [=12=].type != .none } // this doesn't work

遗憾的是,您不能将 == 与具有关联值的 enum 一起使用。您需要使用 模式匹配 ,但这需要在 switchif 语句中完成。

所以,这导致了像这样丑陋的事情:

let filteredArray = array.filter { if case .none = [=10=].type! { return false }; return true }

备注:

  1. 您不能命名您的 enum Type,因为它与 built-in Type 冲突。将其更改为 MyType.

  2. 在自定义 enum 中使用 none 作为案例非常令人困惑,因为它(被人类)与 none可选。由于您的 type 属性 是 可选 ,这使情况变得更糟。在这里我用力解开了它,但这当然很危险。

    你可以这样做:

    if case .none? = [=11=].type
    

    这将显式匹配 none 情况,并将 nil 视为您要保留的内容。

    要过滤掉 nil.none,您可以使用 nil 合并运算符 ??:

    if case .none = ([=12=].type ?? .none)
    

    我建议将 type 声明为 MyClass.MyType 而不是 MyClass.MyType?

我为您提供了一个简单的示例,说明如何在您的上下文中使用带有过滤器函数的枚举。

enum Foo {

  case article(data: [Int])
  case link(data: [String])
  case `none`

  static func myfilter(array: [Foo]) -> [Foo]{
    var newArray:[Foo] = []
    for element in array {
      switch element {
      case .article(let article):
        newArray.append(.article(data: article))
      case .link(let link):
        newArray.append(.link(data: link))
      case .none:
        break
      }
    }
    return newArray
  }
}

let foo: [Foo] = [.article(data: [1,2,3]), .link(data: ["hello", "world"]), .none]

print(Foo.myfilter(array: foo))

我做了一个代码,你可以编译和测试,你必须改变Fooarticlelink的类型。

当你想使用枚举时,你必须使用switch case

如果你绝对想使用 swift 中的过滤器,你可以,但你需要实现协议 Sequence,在这种情况下更复杂。

对于枚举的每个案例,您必须管理一个使用 pattern matching 概念的案例。很给力。