创建一个通用的扩展排序函数

huangapple go评论131阅读模式
英文:

Creating a Generic Sort function in Extension

问题

我想知道我在这里做错了什么。我希望不使用强制转换,但无论我尝试什么,似乎都无法成功。

  1. extension Array where Element: Equatable {
  2. func highestPriority<T: Equatable>(priority: [T]) -> T? {
  3. let sorted = sorted { lhs, rhs in
  4. guard let lhs = priority.firstIndex(of: lhs as! T),
  5. let rhs = priority.firstIndex(of: rhs as! T) else {
  6. return false
  7. }
  8. return lhs < rhs
  9. }
  10. return sorted.first as? T
  11. }
  12. }
  13. public enum Jobs: String, Codable {
  14. case wash = "Wash"
  15. case dry = "Dry"
  16. case wax = "Wax"
  17. }
  18. let priorities: [Jobs] = [.wash, .dry, .wax]
  19. let jobs: [Jobs] = [.wax, .wash, .dry]
  20. let priority = jobs.highestPriority(priority: priorities)

我正在从这个起点进行改进,但我不明白为什么将集合更改为在数组中使用 self 有何不同?

  1. func highestPriority<T: Equatable>(_ collection: [T]?, priority: [T]) -> T? {
  2. let sorted = collection?.sorted { lhs, rhs in
  3. guard let lhs = priority.firstIndex(of: lhs),
  4. let rhs = priority.firstIndex(of: rhs) else {
  5. return false
  6. }
  7. return lhs < rhs
  8. }
  9. return sorted?.first
  10. }
  11. public enum Jobs: String, Codable {
  12. case wash = "Wash"
  13. case dry = "Dry"
  14. case wax = "Wax"
  15. }
  16. let priorities: [Jobs] = [.wash, .dry, .wax]
  17. let jobs: [Jobs] = [.wax, .wash, .dry]
  18. 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.

  1. extension Array where Element : Equatable {
  2. func highestPriority&lt;T: Equatable&gt;( priority: [T]) -&gt; T? {
  3. let sorted = sorted { lhs, rhs in
  4. guard let lhs = priority.firstIndex(of: lhs as! T),
  5. let rhs = priority.firstIndex(of: rhs as! T) else {
  6. return false
  7. }
  8. return lhs &lt; rhs
  9. }
  10. return sorted.first as? T
  11. }
  12. }
  13. public enum Jobs: String, Codable {
  14. case wash = &quot;Wash&quot;
  15. case dry = &quot;Dry&quot;
  16. case wax = &quot;Wax&quot;
  17. }
  18. let priorities: [Jobs] = [.wash, .dry, .wax]
  19. let jobs: [Jobs] = [.wax, .wash, .dry]
  20. 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?

  1. func highestPriority&lt;T:Equatable&gt;(_ collection: [T]?, priority: [T]) -&gt; T? {
  2. let sorted = collection?.sorted { lhs, rhs in
  3. guard let lhs = priority.firstIndex(of: lhs),
  4. let rhs = priority.firstIndex(of: rhs) else {
  5. return false
  6. }
  7. return lhs &lt; rhs
  8. }
  9. return sorted?.first
  10. }
  11. public enum Jobs: String, Codable {
  12. case wash = &quot;Wash&quot;
  13. case dry = &quot;Dry&quot;
  14. case wax = &quot;Wax&quot;
  15. }
  16. let priorities: [Jobs] = [.wash, .dry, .wax]
  17. let jobs: [Jobs] = [.wax, .wash, .dry]
  18. let priority = highestPriority(jobs, priority: priorities)

I have tried changing the generic constraint but I'm just stabbing in the dark 创建一个通用的扩展排序函数

答案1

得分: 2

  1. 由于与 `highestPriority` 关联的所有类型都与数组中存储的类型相同,所以将 `highestPriority` 从通用更改为基于 `Element`
  2. ```swift
  3. extension Array where Element : Equatable {
  4. func highestPriority(priority: [Element]) -> Element? {
  5. let sort = sorted { lhs, rhs in
  6. guard let lhs = priority.firstIndex(of: lhs),
  7. let rhs = priority.firstIndex(of: rhs) else {
  8. return false
  9. }
  10. return lhs < rhs
  11. }
  12. return sort.first
  13. }
  14. }

这是一个更简单的实现:

  1. extension Array where Element : Equatable {
  2. func highestPriority(priority: [Element]) -> Element? {
  3. return priority.first { contains($0) }
  4. }
  5. }

如果数组将具有许多元素(并且元素是可哈希的),那么以下实现可能更有效:

  1. extension Array where Element : Hashable {
  2. func highestPriority(priority: [Element]) -> Element? {
  3. let set = Set(self)
  4. return priority.first { set.contains($0) }
  5. }
  6. }
  1. <details>
  2. <summary>英文:</summary>
  3. 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`.
  4. ```swift
  5. extension Array where Element : Equatable {
  6. func highestPriority(priority: [Element]) -&gt; Element? {
  7. let sort = sorted { lhs, rhs in
  8. guard let lhs = priority.firstIndex(of: lhs),
  9. let rhs = priority.firstIndex(of: rhs) else {
  10. return false
  11. }
  12. return lhs &lt; rhs
  13. }
  14. return sort.first
  15. }
  16. }

Here's a much simpler implementation:

  1. extension Array where Element : Equatable {
  2. func highestPriority( priority: [Element]) -&gt; Element? {
  3. return priority.first { contains($0) }
  4. }
  5. }

If the array will have a lot of elements (and the elements are Hashable), it would likely be more efficient as:

  1. extension Array where Element : Hashable {
  2. func highestPriority(priority: [Element]) -&gt; Element? {
  3. let set = Set(self)
  4. return priority.first { set.contains($0) }
  5. }
  6. }

huangapple
  • 本文由 发表于 2023年8月4日 01:16:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定