Reputation: 32054
Say I have a simple Ingredient
class:
class Ingredient {
let section : String // 'Produce', 'Spices', 'Dairy', 'Grains'
}
And I have a pile of Ingredient
items:
var ingredients : [Ingredient] = ...
I want to collect the number of distinct sections from these ingredients.
I can do this in Java via (relying on the auto-clumping of Set
types):
ingredients.stream().map(Ingredient::getSection).collect(Collectors.toSet()).count()
Or, using the distinct()
method:
ingredients.stream().map(Ingredient::getSection).distinct().count()
But I'm looking for a way to do a similar one-liner in Swift. Some of the research I've done shows people writing their own methods to collect distinct values, but I was hoping there would be a distinct()
or Set
-collecting method for Swift types.
Upvotes: 3
Views: 2561
Reputation: 23
Using Swift 3, and keeping O(n) complexity it looks like this:
extension Array where Element: Hashable {
func distinct() -> Array<Element> {
return Array(Set(self))
}
}
Upvotes: 2
Reputation: 130102
It's the same mostly, you should use the Set
type:
let ingredients = [Ingredient(section: "Produce"), Ingredient(section: "Produce"), Ingredient(section: "Spices"), Ingredient(section: "Dairy")]
let sections = Set(ingredients.map{ $0.section })
let numDistinctSections = Set(ingredients.map{ $0.section }).count
Also, nothing simpler than declaring your own distinct
function:
extension CollectionType where Generator.Element : Hashable {
func distinct() -> [Generator.Element] {
return Array(Set(self))
}
}
let sections = ingredients.map{ $0.section }.distinct()
Upvotes: 4
Reputation: 5787
Sure. Turn your sections into a [String]
, use that to create a Set
and get the count like this:
let numUnique = Set(ingredients.map({ $0.section })).count
Upvotes: 2
Reputation: 80811
Sure, you can do this in much the same way by mapping over your ingredients array to extract an array of sections – you can then convert these to a Set
and get out the count, giving you the number of distinct sections.
let distinctSections = Set(ingredients.map{$0.section}).count
Upvotes: 8