Swift 5,自定义对象数组,最小值.不等于同一数组中的其他值



如何确定此数组是否只有一个最低值

let scoresExampleOne = [2, 2, 3, 4] // return false
let scoresExampleTwo = [2, 3, 3, 5] // return true 

"scoreValues";嵌入到自定义的";玩家";对象

为了这个问题,我只是想把它简化一下。

您所需要的只是迭代您的集合并跟踪最小值,以及它是否重复:

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)
}
}

游乐场测试:

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)
func isSingleLowestValue(scores: [Int]) -> Bool {
guard let min = scores.min() else { return false }
let minCount = scores.lazy.filter { $0 == min }.count
return minCount == 1
}

Leo的答案很好,但这是extremum方法的一个特例。

public extension Sequence {
/// The first element of the sequence.
/// - Note: `nil` if the sequence is empty.
var first: Element? {
var iterator = makeIterator()
return iterator.next()
}
/// - Parameters:
///   - comparable: The property to compare.
///   - areSorted: Whether the elements are in order, approaching the extremum.
func extremum<Comparable: Swift.Comparable>(
comparing comparable: (Element) throws -> Comparable,
areSorted: (Comparable, Comparable) throws -> Bool
) rethrows -> Extremum<Element>? {
try first.map { first in
try dropFirst().reduce(into: .init(value: first, count: 1)) {
let comparables = (try comparable($0.value), try comparable($1))
if try areSorted(comparables.0, comparables.1) {
$0 = .init(value: $1, count: 1)
} else if (comparables.0 == comparables.1) {
$0.count += 1
}
}
}
}
/// - throws: `Extremum<Element>.UniqueError`
func uniqueMin<Comparable: Swift.Comparable>(
comparing comparable: (Element) throws -> Comparable
) throws -> Extremum<Element> {
typealias Error = Extremum<Element>.UniqueError
guard let extremum = try extremum(comparing: comparable, areSorted: >)
else { throw Error.emptySequence }
guard extremum.count == 1
else { throw Error.notUnique(extremum) }
return extremum
}
}
public struct Extremum<Value> {
enum UniqueError: Swift.Error {
case emptySequence
case notUnique(Extremum)
}
var value: Value
var count: Int
}

最新更新