如何处理 reduce 函数的初始 nil 值

How to handle initial nil value for reduce functions

我想在Swift学习和使用更多的函数式编程。所以,我一直在操场上尝试各种事情。不过,我不明白 Reduce。基本的教科书示例有效,但我无法解决这个问题。

我有一个名为 "toDoItems" 的字符串数组。我想得到这个数组中最长的字符串。在这种情况下处理初始 nil 值的最佳做法是什么?我认为这可能经常发生。我想写一个自定义函数并使用它。

func optionalMax(maxSofar: Int?, newElement: Int) -> Int {
    if let definiteMaxSofar = maxSofar {
        return max(definiteMaxSofar, newElement)
    }
    return newElement
}   

// Just testing - nums is an array of Ints. Works.
var maxValueOfInts = nums.reduce(0) { optionalMax([=10=], ) }   

// ERROR: cannot invoke 'reduce' with an argument list of type ‘(nil, (_,_)->_)'
var longestOfStrings = toDoItems.reduce(nil) { optionalMax(count([=10=]), count()) }

用空字符串 "" 而不是 nil 初始化它。或者你甚至可以用数组的第一个元素初始化它,但空字符串似乎更好。

可能只是 Swift 不会自动推断初始值的类型。尝试通过显式声明使其清楚:

var longestOfStrings = toDoItems.reduce(nil as Int?) { optionalMax([=10=], count()) }

顺便说一下,我不指望 [=12=](你的累加器),因为它不是 String,而是一个可选的 Int Int?

一般来说,为了避免以后阅读代码时出现混淆,我明确地将累加器标记为 a 并将来自系列的元素标记为 x:

var longestOfStrings = toDoItems.reduce(nil as Int?) { a, x in optionalMax(a, count(x)) }

这种方式在使用累加器或单个元素时,在代码中应该比[=12=]更清晰。

希望对您有所帮助

在写了一些错误的代码之后再进行此操作,如果您对将空字符串 return 编辑为空数组感到满意,这将是 return 最长的字符串:

toDoItems.reduce("") { count([=10=]) > count() ? [=10=] : }

或者如果你想要零,使用

toDoItems.reduce(nil as String?) { count([=11=]!) > count() ? [=11=] : }

问题是,如果您使用 nil 作为种子,编译器无法推断您用于种子和累加器闭包的类型,并且在将可选字符串用作 $0 时,您还需要获得正确的可选类型。