Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle initial nil value for reduce functions

I would like to learn and use more functional programming in Swift. So, I've been trying various things in playground. I don't understand Reduce, though. The basic textbook examples work, but I can't get my head around this problem.

I have an array of strings called "toDoItems". I would like to get the longest string in this array. What is the best practice for handling the initial nil value in such cases? I think this probably happens often. I thought of writing a custom function and use it.

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)) }
like image 374
Daniel Avatar asked Jun 19 '15 08:06

Daniel


2 Answers

It might just be that Swift does not automatically infer the type of your initial value. Try making it clear by explicitly declaring it:

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

By the way notice that I do not count on $0 (your accumulator) since it is not a String but an optional Int Int?

Generally to avoid confusion reading the code later, I explicitly label the accumulator as a and the element coming in from the serie as x:

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

This way should be clearer than $0 and $1 in code when the accumulator or the single element are used.

Hope this helps

like image 114
Matteo Piombo Avatar answered Oct 06 '22 01:10

Matteo Piombo


Initialise it with an empty string "" rather than nil. Or you could even initialise it with the first element of the array, but an empty string seems better.

like image 28
rounak Avatar answered Oct 06 '22 00:10

rounak