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

时间:2015-06-19 08:09:35

标签: swift functional-programming reduce

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

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

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($0, $1) }   

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

3 个答案:

答案 0 :(得分:3)

可能只是Swift不会自动推断出初始值的类型。尝试通过明确声明来明确它:

var longestOfStrings = toDoItems.reduce(nil as Int?) { optionalMax($0, count($1)) }

请注意,我不依赖于$0(您的累加器),因为它不是String,而是可选的Int Int?

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

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

当使用累加器或单个元素时,这种方式应该比代码中的$0$1更清晰。

希望这有帮助

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

  

toDoItems.reduce(“”){count($ 0)>算($ 1)? $ 0:$ 1}

或者如果你想要零,请使用

  

toDoItems.reduce(nil as String?){count($ 0!)>算($ 1)? $ 0:$ 1}

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