如何从类数组中获取不同的值?

时间:2018-03-30 14:26:44

标签: swift xcode

我发现了很多关于如何从数组中获取不同值的示例:

[1, 2, 2, 3, 4, 5, 6]

然后我可以Array(Set(myArray)),但是,当数组值是类时,这不起作用。

但是,我需要的是从类中的类的属性中获取不同值的列表,例如此类:

class Alert: Decodable {
    var id: Int?

    var category: String?
    var category_id: Int?

    var summary: String?
    var title: String?
    var publish_date: String?

}

我想从我的数组中获取“类别”列表。

我知道我可能只是遍历数组,如果该值不存在则附加一个新数组。不确定这是否是最有效的方式,或者是否有更加敏捷的做事方式。

我发现我可以做到:

let categories = self.items!.map { $0.category }

哪个会获得类别列表,但不知道如何使它们分明。我试过Array(Set(,但这不起作用。我收到以下错误:

  

无法推断通用参数“元素”

我对swift相对较新,所以我知道我想做什么,只是无法在语法上弄明白。

任何指导将不胜感激。

2 个答案:

答案 0 :(得分:2)

Set要求您的元素为Hashable。这意味着它们必须为Equatable并提供散列值。

如果您的目标是创建唯一类别列表,那么您应该首先创建一个类别数组:

let categories = (self.items ?? []).compactMap { $0.category }

然后,您只需使用Set获取唯一类别:

let uniqueCategories = Array(Set(categories))

但请注意,Set不会保留订购的商品。如果您还需要保持categories顺序,那么我建议您使用简单的Array扩展程序:

extension Array where Element: Hashable {
    func distinct() -> Array<Element> {
        var set = Set<Element>()
        return filter {
            guard !set.contains($0) else { return false }
            set.insert($0)
            return true
        }
    }
}

或使用Set.insert返回值(Leo Dabus的想法)进行简化:

extension Array where Element: Hashable {
    func distinct() -> Array<Element> {
        var set = Set<Element>()
        return filter { set.insert($0).inserted }
    }
}

然后

let uniqueCategories = (self.items ?? [])
   .flatMap { $0.category }
   .distinct()

答案 1 :(得分:0)

我找到了我想要的答案。如果我提取这样的类别:

let categories = self.items!.map({ (alert: Alert) -> String in
    alert.category!
})

然后我可以获得不同的列表:

print(Array(Set(categories)))

它会起作用。

这可能不是最好的方式,但我发布这个作为答案,直到有人发布更好的方式。