我想在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)) }
答案 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时,还需要使可选类型正确。