Фильтровать массив элементов по свойству enum со связанным значением
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 { $0.type != .none } // this doesn't work
2 ответа
К сожалению, вы не можете использовать ==
с участием enum
с соответствующими значениями. Вы должны использовать сопоставление с образцом, но это должно быть сделано в switch
или же if
заявление.
Итак, это приводит к чему-то ужасному:
let filteredArray = array.filter { if case .none = $0.type! { return false }; return true }
Примечания:
Вы не можете назвать свой
enum
Type
потому что это конфликтует со встроеннымType
, Измените это на что-то вродеMyType
,Это очень запутанно использовать
none
как случай в обычаеenum
потому что это путается (людьми) сnone
в необязательном. Это усугубляется тем, что вашtype
свойство необязательно. Здесь я развернул его силой, но это, конечно, опасно.Вы могли бы сделать:
if case .none? = $0.type
Это будет соответствовать
none
дело явно и лечитьnil
как то, что вы хотите сохранить.Отфильтровать
nil
а также.none
, вы можете использовать оператор слияния ноль??
:if case .none = ($0.type ?? .none)
Я бы предложил объявить
type
какMyClass.MyType
вместоMyClass.MyType?
,
Я сделал вам простой пример того, как использовать enum в вашем контексте с функцией фильтра.
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))
Я сделал код, который вы можете скомпилировать и протестировать, вы должны изменить тип для Foo
, article
а также link
,
Если вы хотите использовать перечисление, вы должны использовать switch case
,
Если вы абсолютно хотите использовать фильтр в swift, вы можете, но вам нужно реализовать Sequence протокола, который в этом случае является более сложным.
Для каждого случая вашего перечисления вы должны управлять случаем, который использует концепцию сопоставления с образцом. Это очень мощно.