# Chapter 19 Pg 415 Functional Programming

I’m really interested in Functional Programming, and have made it a point to use `map(_:), filter(_:)` etc wherever possible while following the iOS tutorials.

I chose to use `filter(_:)` for the following method:

``````func countUncheckedItems() -> Int {
var count = 0
for item in items where !item.checked {
count += 1
}
return count
}
``````

my method using `filter(_:)`

``````func countUncheckedItems() -> Int {
return items.filter { item in !item.checked }.count
}
``````

A few pages down I found that the author took a moment to make an example of this method as an intro to Functional Programing and wrote the method using `reduce(_:_:)` which got me thinking…

``````func countUncheckedItems() -> Int {
return items.reduce(0) { cnt, item in cnt + (item.checked ? 0 : 1) }
}
``````

I understand how to use both, but as a beginner I worry that there is a reason unbeknownst to me as to why filter was not used instead.
If it’s a matter of style / the author’s preference that’s fine.
I am just concerned that perhaps there is a situation where using filter here would fail, and reduce is the better option because it will always produce the same output - which is the goal in functional programming.

Could someone clear it up?
Thanks

I would say both ways will work reliably. The main difference is that filter builds a new list, from which you then get the count; while reduce traverses the existing list, adding a 1 or a 0 to the running total. So reduce does not build a new list, which means less memory use. Reduce is arguably a more direct expression of your intention here, which is also a goal of functional programming.

1 Like

ahh!!! Brilliant! Thank you so much for your reply!
I’m SUPER interested in functional programming.

So would you consider it self mutating?
I’m making a correlation between it being named reduce(), not reduced() and sort() (which self mutates) vs sorted() which will make a new array?

Again thanks so much!

No, Reduce does not change the array, and does not return an array either. It returns a single value, the result of calling the closure for each element in the array. Filter also does not mutate, it returns a new array.

The dual syntax ala “sort” and “sorted” seems to occur when it could either change the array or return a new array.

1 Like

Understood.
tbh reduce() is the weakest of all my understandings of Swift’s first class funcs - my exposure to it has been simple: sum arrays/sequences so I wasn’t at all excited about it. Your info is much appreciated, I have a new respect and interest in `reduce(_:)`

I prefer the trailing closure syntax with shorthand param/arg names because the patterns seem clearer to me. I was able to fool around with reduce and get this to do the same desired affect as the author’s reduce with param names.

``````  func countUncheckedItems() -> Int {
return items.reduce(0) { \$0 + (\$1.checked ? 0 : 1) }
}
``````

In terms of `sort(by:)`: Chapter 19, pg 417

The Author's code
``````func sortChecklists() {
lists.sort(by: { (checklist1, checklist2) -> Bool in
return checklist1.name.localizedStandardCompare(checklist2.name) == .orderedAscending })
}
``````

I thought conforming `lists` type `Checklist` to Comparable would be awesome so that I could REALY simplify the `sort(by:)` method

extension Checklist: Comparable & implementation
``````extension Checklist: Comparable {
static func < (lhs: Checklist, rhs: Checklist) -> Bool {
return lhs.name < rhs.name
}
}

func sortChecklists() {
return lists.sort(by: <)
}
``````

My thoughts are either that the author did not wish to go into details on how to implement an Equatable/Conformable protocol, or that there is a good reason why it was written as such.

I have never seen the method `.localizedStandardCompare` before and the Documentation states it’s a Generic instant Method on StringProtocol.

Is it used primarily if the coder does not expect to utilize Comparable more than once? Is having Checklist adopt the protocol overkill?

I think the reason not to adopt Comparable as you have suggested is that CheckListItems don’t have a natural sort order. CheckListItems could be sorted by name, or by date, or by checked and then date, and so on. Comparable is usually for things that act like a single value and have one natural way to sort them.

.localizedStandardCompare is from NSString, and makes file name comparisons the same in different locales. I don’t think it is needed here; swift lets you just use operators:
`a.name < b.name`

1 Like

Ah, I see.
Thank you very much for clearing all of this up, I have learned so much!

For anyone interested, here are 2 ways to write the sortChecklists() definition with trailing syntax & shorthand parameters/arguments:

``````  func sortChecklists() {
return lists.sort(by: { \$0.name < \$1.name } )
}

func sortChecklists() {
return lists.sort { \$0.name < \$1.name }
}
``````
1 Like

This topic was automatically closed after 166 days. New replies are no longer allowed.