Swift 高阶函数赋值

Swift 高阶函数赋值,swift,generics,Swift,Generics,我正在学习Swift中的高阶函数(如.map.filter.reduce…)和泛型类型 以下是我的功能: func max<T: Comparable>(_ array: [T]) -> T { var max = 0 as! T for value in array { if value > max { max = value } } return max } 对于INT,您可能希望使用reduce进行类似的操作:

我正在学习Swift中的高阶函数(如.map.filter.reduce…)和泛型类型

以下是我的功能:

func max<T: Comparable>(_ array: [T]) -> T {
    var max = 0 as! T

    for value in array {
        if value > max { max = value }
    }

    return max
}

对于INT,您可能希望使用
reduce
进行类似的操作:

// Reduce with initial value the first value of the array if available,
// or 0 otherwise
let max = array.reduce(array.first ?? 0) { (max, newValue) -> T in
    return newValue > max ? newValue : max 
}
更新

你想要JeremyP的答案来正确处理所有可比较的问题

减少

return array.reduce(nil)
{
    (max: T?, current: T) -> T? in
    guard let max = max else { return current }
    return max > current ? max : current
}
这将返回一个可选的,但考虑到您可能传入一个空数组,这可能是合理的

当然也有这个

你的问题的含义是这是一个学习练习。这是一个利用高阶函数的广义解。请注意,Swft Strandard库已经包含了一个执行此操作的函数

extension Array 
{
     func pickOne(choose: (Element, Element) -> Element) -> Element?
     {
         return self.reduce(nil)
         {
             (bestSoFar: Element?, current: Element) -> Element? in
             guard let bestSoFar = bestSoFar else { return current }
             return choose(bestSoFar, current)
         }
     }
}
因此,max的功能现在定义如下:

array.pickOne { $0 > $1 ? $0 : $1 }
而敏会是

array.pickOne { $0 < $1 ? $0 : $1 }
array.pickOne{$0<$1?$0:$1}

首先请注意,您对“初始值”和强制 铸造

有两个问题:

  • 对于不包含整数的数组,例如
    max([“a”,“b”]
    ),它将崩溃
  • 即使对于整数数组,如果所有数组元素都是 负数,例如
    max([-2,-3])
    应该是
    -2
    而不是零
因此,最好选择第一个数组元素作为初始值 “强制归零”的定义

这引出了下一个问题:如果数组 是空的吗?有两种有效的方法:您可以要求 函数是使用非空数组(和 前提条件):

第二个呢

/// Compute the maximal element in an array.
///
/// - Returns: `nil` if the array is empty, and the maximal element otherwise.
func max<T: Comparable>(_ array: [T]) -> T? {
    guard let first = array.first else { return nil }
    return array.reduce(first) { $0 > $1 ? $0 : $1 }
}
最后,您可以使用现有的

func max<T : Comparable>(_ x: T, _ y: T) -> T
func max(x:T,y:T)->T
函数而不是上述所有示例中的文字闭包,例如

/// Compute the maximal element in an array.
///
/// - Returns: `nil` if the array is empty, and the maximal element otherwise.
func max<T: Comparable>(_ array: [T]) -> T? {
    return array.first.flatMap { array.reduce($0, max) }
}
///计算数组中的最大元素。
///
///-如果数组为空,则返回`nil',否则返回最大元素。
func max(u数组:[T])->T?{
返回array.first.flatMap{array.reduce($0,max)}
}

max([-3,-2])
返回
0
,然后
max([“a”,“b”]
崩溃。你说得对!此方法需要进行一些严重的修复!如果数组
[-1,-2]
?我考虑过投反对票,但这个问题也有相同的错误。另外,如果0不能转换为T怎么办?@JeremyP你是对的,我现在知道我假设它是Int,并相应地更新了答案。你的答案是正确的,因为它在没有假设的情况下处理可比性。我第一次尝试回答这个问题时遇到了相同的问题我用了0,然后我想,负数呢,所以我写了
Int.min
,然后我想,它不一定是
Int
/// Compute the maximal element in an array.
///
/// - Returns: `nil` if the array is empty, and the maximal element otherwise.
func max<T: Comparable>(_ array: [T]) -> T? {

    guard var max = array.first else { return nil }
    for value in array {
        if value > max { max = value }
    }
    return max
}
/// Compute the maximal element in an array.
///
/// - Returns: The maximal element.
///
/// - Note: The array must not be empty.
func max<T: Comparable>(_ array: [T]) -> T {
    precondition(!array.isEmpty, "`max` called with empty array")
    return array.reduce(array[0]) { $0 > $1 ? $0 : $1 }
}
/// Compute the maximal element in an array.
///
/// - Returns: `nil` if the array is empty, and the maximal element otherwise.
func max<T: Comparable>(_ array: [T]) -> T? {
    guard let first = array.first else { return nil }
    return array.reduce(first) { $0 > $1 ? $0 : $1 }
}
/// Compute the maximal element in an array.
///
/// - Returns: `nil` if the array is empty, and the maximal element otherwise.
func max<T: Comparable>(_ array: [T]) -> T? {
    return array.first.flatMap { array.reduce($0) { $0 > $1 ? $0 : $1 } }
}
func max<T : Comparable>(_ x: T, _ y: T) -> T
/// Compute the maximal element in an array.
///
/// - Returns: `nil` if the array is empty, and the maximal element otherwise.
func max<T: Comparable>(_ array: [T]) -> T? {
    return array.first.flatMap { array.reduce($0, max) }
}