Dan*_*iel 5 generics functional-programming swift
我想创建一个通常用于函数式编程的通用find().在函数式编程中,您不能使用数组索引和for循环.你过滤了.它的工作方式是,如果你有一个说清单
["apple", "banana", "cherry"]
Run Code Online (Sandbox Code Playgroud)
并且您想要找到banana,然后通过创建元组将数组索引分配给列表元素
[(1, "apple"), (2, "banana"), (3, "cherry")]
Run Code Online (Sandbox Code Playgroud)
现在,您可以过滤到"banana"并返回索引值.
我试图为此创建一个通用函数,但我收到一个错误.这个语法出了什么问题?
func findInGenericIndexedList<T>(indexedList: [(index: Int, value: T)], element: (index: Int, value: T)) -> Int? {
let found = indexedList.filter { // ERROR: Cannot invoke 'filter' with an argument list of type '((_) -> _)'
element.value === $0.value
}
if let definiteFound = found.first {
return definiteFound.index
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
更新1:我想使用上面的解决方案而不是使用find()(将被弃用)或者使用Swift 2.0 indexOf(),因为我试图遵循功能编程范例,依赖于通用函数而不是类方法.
完成这项工作所需的最小更改是使 T 符合 Equatable 并使用 == 运算符。
func findInGenericIndexedList<T:Equatable>(indexedList: [(index: Int, value: T)], element: (index: Int, value: T)) -> Int? {
let found = indexedList.filter {
element.value == $0.value
}
if let definiteFound = found.first {
return definiteFound.index
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
在这里使用 === 并没有什么意义,因为通常会将其应用于值类型(特别是如果您遵循函数范式),而这从来都不是真的。
除此之外,我花了一些时间思考这个问题,这就是我会做的:
extension Array where Element : Equatable {
func find(element:Array.Generator.Element) -> Int? {
let indexedList = lazy(self.enumerate())
let found = indexedList.filter {
element == $1
}
let definiteFound = found.prefix(1)
return definiteFound.generate().next()?.index
}
}
Run Code Online (Sandbox Code Playgroud)
数组上的协议扩展,因为它使语法更整洁,惰性序列避免检查每个元素,0 索引。
| 归档时间: |
|
| 查看次数: |
859 次 |
| 最近记录: |