英文:
Creating a Generic Sort function in Extension
问题
我想知道我在这里做错了什么。我希望不使用强制转换,但无论我尝试什么,似乎都无法成功。
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)
我正在从这个起点进行改进,但我不明白为什么将集合更改为在数组中使用 self 有何不同?
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 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
答案1
得分: 2
由于与 `highestPriority` 关联的所有类型都与数组中存储的类型相同,所以将 `highestPriority` 从通用更改为基于 `Element`。
```swift
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
}
}
这是一个更简单的实现:
extension Array where Element : Equatable {
func highestPriority(priority: [Element]) -> Element? {
return priority.first { contains($0) }
}
}
如果数组将具有许多元素(并且元素是可哈希的),那么以下实现可能更有效:
extension Array where Element : Hashable {
func highestPriority(priority: [Element]) -> Element? {
let set = Set(self)
return priority.first { set.contains($0) }
}
}
<details>
<summary>英文:</summary>
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`.
```swift
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) }
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论