I would like to know what I am doing wrong here. I would like not to use force casting but no matter what I try I do not seem able to.
extension Array where Element : Equatable {
func highestPriority<T: Equatable>( priority: [T]) -> T? {
let sorted = sorted { lhs, rhs in
guard let lhs = priority.firstIndex(of: lhs as! T),
let rhs = priority.firstIndex(of: rhs as! T) else {
return false
}
return lhs < rhs
}
return sorted.first as? T
}
}
public enum Jobs: String, Codable {
case wash = "Wash"
case dry = "Dry"
case wax = "Wax"
}
let priorities: [Jobs] = [.wash, .dry, .wax]
let jobs: [Jobs] = [.wax, .wash, .dry]
let priority = jobs.highestPriority(priority: priorities)
Im refining from this which works, but I'm not understanding why changing collection to use self in Array is any different?
func highestPriority<T:Equatable>(_ collection: [T]?, priority: [T]) -> T? {
let sorted = collection?.sorted { lhs, rhs in
guard let lhs = priority.firstIndex(of: lhs),
let rhs = priority.firstIndex(of: rhs) else {
return false
}
return lhs < rhs
}
return sorted?.first
}
public enum Jobs: String, Codable {
case wash = "Wash"
case dry = "Dry"
case wax = "Wax"
}
let priorities: [Jobs] = [.wash, .dry, .wax]
let jobs: [Jobs] = [.wax, .wash, .dry]
let priority = highestPriority(jobs, priority: priorities)
I have tried changing the generic constraint but I'm just stabbing in the dark :D
Since all of the types associated with highestPriority
are the same as the type stored in the array, change highestPriority
from being generic to being based on Element
.
extension Array where Element : Equatable {
func highestPriority(priority: [Element]) -> Element? {
let sort = sorted { lhs, rhs in
guard let lhs = priority.firstIndex(of: lhs),
let rhs = priority.firstIndex(of: rhs) else {
return false
}
return lhs < rhs
}
return sort.first
}
}
Here's a much simpler implementation:
extension Array where Element : Equatable {
func highestPriority( priority: [Element]) -> Element? {
return priority.first { contains($0) }
}
}
If the array will have a lot of elements (and the elements are Hashable), it would likely be more efficient as:
extension Array where Element : Hashable {
func highestPriority(priority: [Element]) -> Element? {
let set = Set(self)
return priority.first { set.contains($0) }
}
}