I've found many examples on how to get the distinct values from an array such as this:
[1, 2, 2, 3, 4, 5, 6]
And then I can do Array(Set(myArray))
, however, this doesn't work when the array value is a class.
However, what I need is to get a list of distinct values from a property of a class that is in an array such as this class:
class Alert: Decodable {
var id: Int?
var category: String?
var category_id: Int?
var summary: String?
var title: String?
var publish_date: String?
}
I'd like to get a list of "category" from my array.
I know I can probably just loop through the array, and append a new array if the value doesn't exist. Not sure if this is the most effective way, or if there is a more swifty way of doing things.
I found I can do:
let categories = self.items!.map { $0.category }
Which will get a list of the categories, but not sure how to make them distinct. I tried Array(Set(
, but that doesn't work. I get the following error:
Generic parameter 'Element' could not be inferred
I'm relatively new to swift, so I know what I want to do, just can't figure it out syntactically.
Any guidance will be appreciated.
Set
requires your elements to be Hashable
. That means they have to be Equatable
and provide a hashing value.
If your aim is to create list of unique categories, then you should start by creating an array of categories:
let categories = (self.items ?? []).compactMap { $0.category }
Then you can simply get unique categories using Set
:
let uniqueCategories = Array(Set(categories))
However, note that Set
does not keep items ordered. If you also need to keep the categories
in order then I would recommend a simple Array
extension:
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
}
}
}
or simplified using Set.insert
return value (Leo Dabus's idea):
extension Array where Element: Hashable {
func distinct() -> Array<Element> {
var set = Set<Element>()
return filter { set.insert($0).inserted }
}
}
and then
let uniqueCategories = (self.items ?? [])
.flatMap { $0.category }
.distinct()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With