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

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

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&lt;T: Equatable&gt;( priority: [T]) -&gt; 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 &lt; rhs
        }
        return sorted.first as? T
    }
}

public enum Jobs: String, Codable {
    case wash = &quot;Wash&quot;
    case dry = &quot;Dry&quot;
    case wax = &quot;Wax&quot;
}

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&lt;T:Equatable&gt;(_ collection: [T]?, priority: [T]) -&gt; 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 &lt; rhs
    }
    return sorted?.first
}

public enum Jobs: String, Codable {
    case wash = &quot;Wash&quot;
    case dry = &quot;Dry&quot;
    case wax = &quot;Wax&quot;
}

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]) -&gt; 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 &lt; rhs
        }

        return sort.first
    }
}

Here's a much simpler implementation:

extension Array where Element : Equatable {
    func highestPriority( priority: [Element]) -&gt; 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]) -&gt; Element? {
        let set = Set(self)
        return priority.first { set.contains($0) }
    }
}

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:

确定