All you need is to iterate your collection and keep track of the minimum value and if it repeats or not:
extension Collection {
func minElement<T: Comparable>(_ predicate: (Element) -> T) -> (element: Element, single: Bool)? {
guard var minElement = first else { return nil }
var min = predicate(minElement)
var single = true
for element in dropFirst() {
let value = predicate(element)
if value > min { continue }
if value < min {
minElement = element
min = value
single = true
} else {
single = false
}
}
return (minElement, single)
}
func min<T: Comparable>(_ predicate: (Element) -> T) -> (min: T, single: Bool)? {
guard let (element, single) = minElement(predicate) else { return nil }
return (predicate(element), single)
}
}
Playground testing:
struct Player {
let score: Int
}
let players1: [Player] = [.init(score: 2),
.init(score: 2),
.init(score: 3),
.init(score: 4)]
let players2: [Player] = [.init(score: 2),
.init(score: 3),
.init(score: 3),
.init(score: 5)]
let scoresExampleOne = players1.min(\.score) // (min 2, single false)
let scoresExampleTwo = players2.min(\.score) // (min 2, single true)
let scoresExampleThree = players1.minElement(\.score) // ({score 2}, single false)
let scoresExampleFour = players2.minElement(\.score) // ({score 2}, single true)