有两个参数的Swift过滤器是否有更优雅的语法

Rya*_*ner 2 swift

是否有更优雅的方式来过滤附加参数(或map,reduce).

当我使用单个参数进行过滤时,我们可以获得一个简单易用的语法

let numbers = Array(1...10)

func isGreaterThan5(number:Int) -> Bool {
    return number > 5
}

numbers.filter(isGreaterThan5)
Run Code Online (Sandbox Code Playgroud)

但是,如果我需要将一个额外的参数传递给我的函数,那么结果很难看

func isGreaterThanX(number:Int,x:Int) -> Bool {
    return number > x
}

numbers.filter { (number) -> Bool in
    isGreaterThanX(number: number, x: 8)
}
Run Code Online (Sandbox Code Playgroud)

我想用类似的东西

numbers.filter(isGreaterThanX(number: $0, x: 3))
Run Code Online (Sandbox Code Playgroud)

但是这给出了一个未包含在闭包中的编译错误匿名闭包参数

Mar*_*n R 8

您可以更改函数以返回一个闭包,该闭包用作过滤器方法的谓词:

func isGreaterThan(_ lowerBound: Int) -> (Int) -> Bool {
    return { $0 > lowerBound }
}

let filtered = numbers.filter(isGreaterThan(5))
Run Code Online (Sandbox Code Playgroud)

isGreaterThan是一个接受Int参数并返回类型闭包的函数(Int) -> Bool.返回的闭包"捕获"给定下限的值.

如果你使函数通用,那么它也可以与其他类似的类型一起使用:

func isGreaterThan<T: Comparable>(_ lowerBound: T) -> (T) -> Bool {
    return { $0 > lowerBound }
}

print(["D", "C", "B", "A"].filter(isGreaterThan("B")))
Run Code Online (Sandbox Code Playgroud)

但是,在这种特殊情况下,字面闭包也很容易阅读:

let filtered = numbers.filter( { $0 > 5 })
Run Code Online (Sandbox Code Playgroud)

并且只是为了完整性:使用实例方法是Swift中的Curried函数的事实 ,这也可以工作:

extension Comparable {
    func greaterThanFilter(value: Self) -> Bool {
        return value > self
    }
}

let filtered = numbers.filter(5.greaterThanFilter)
Run Code Online (Sandbox Code Playgroud)

但"逆转逻辑"可能令人困惑.


备注:在早期的Swift版本中,您可以使用curried函数语法:

func isGreaterThan(lowerBound: Int)(value: Int) -> Bool {
    return  value > lowerBound
}
Run Code Online (Sandbox Code Playgroud)

但是在Swift 3中删除了这个功能.