# Chapter 10 HIITFit challenge folder

Hi. So I have been following along the excellent tutorial until Chapter 10 when we are asked to do the challenge to fix the design of HIITFit. The project supplied in the challenge directory contains some new code that I especially do not understand and I was hoping for some clarification.
My question is on the code that was written in the .onAppear modifier, I will paste it below. I was adding my own comments to better understand what is going on

var body: some View {
VStack {
HStack {
ForEach(0â€¦<7) { index in
bar(day: index, size: geometry.size)
}
}
Divider()
Spacer()
}
.onAppear {
days = Date().lastSevenDays //array of dates from past week
exercisesForWeek = ExerciseDay
let counts: [Int] = days.map { day in
let foundDate = exercisesForWeek.filter {
\$0.date.yearMonthDay == day.yearMonthDay
}
return foundDate.first?.exercises.count ?? 0
//returns the number of exercises completed for the first day
}
assert(counts.count == 7)
// remap values to 0 to maxBarHeight
let maxValue = max(counts.max() ?? 0, 1)
countsForWeek = counts.map {
\$0 * maxBarHeight / maxValue
}
}

I understand that foundDate is an array of ExerciseDays, an array of exercises that were completed in the past week, and that counts as an array of integers, is an array of the number of exercises that were completed in the first day, the first ExerciseDay element

return foundDate.first?.exercises.count ?? 0

My question is, what is the purpose of counts as a value, since it is the number of exercises done on the first day? And given that our development data does not have 7 exercises, what is the purpose of the assert line?

assert(counts.count == 7)

The assertion is going to fail every time, and I am positively flummoxed as to the logic behind this code. Any help would be appreciated, if I hope to reproduce what I have learnt in an app of my own I feel I have to understand the logic behind the supplied code.

Hi @supernova2108, and welcome to the forum !

You can format your code blocks using a backtick `

Use three of them before and after the code block

``````This is a code block surrounded by ```
``````

It means that the post renderer wonâ€™t try and do clever things, for example, it lost the important line:

``````exercisesForWeek = [ExerciseDay](history.exerciseDays.prefix(7))
``````

As for your question, I hope I can resolve the confusion.

Going through the code:

`days` is an array that contains seven dates for the last seven days. eg `[2021-11-11, 2021-11-12, ...., 2021-11-17]`

`exercisesForWeek` is an array that contains a maximum of seven exercises in the format:

``````id: BE209DAC-CC72-42FA-B01B-80DB3CF50D09,
date: 2021-11-17 01:18:04 +0000,
exercises: ["Step Up"]
``````

The chart drawing is easier if there are always seven data points for the week, one for the count of each day, but if youâ€™ve only done one exercise, then you only have one data point.

So in an ideal world, `counts` will contain seven entries and then the chart drawing is easier. Thatâ€™s what the `assert` does - it makes sure there are seven entries in `counts`.

``````let counts: [Int] = days.map { day in
}
``````

This code will iterate through `days`. We already know that there are seven entries in `days`, so there will be seven iterations, each using `day`. Therefore `counts` will end up having seven entries.

``````let foundDate = exercisesForWeek.filter {
\$0.date.yearMonthDay == day.yearMonthDay
}
``````

Here you filter `exercisesForWeek` so that `foundDate` is an array that contains only the exercises performed on the `day` currently being processed in the `map` loop.

If there are no entries for a particular day, then `foundDate` will be empty, otherwise it will contain the single `ExerciseDay` for that day.

``````return foundDate.first?.exercises.count ?? 0
``````

You then get the first entry in `foundDate`. If `foundDate` is empty, then there is no first entry. In that case, the zero after the `??` is returned.
Otherwise, the first entryâ€™s count of exercises performed is returned.

Itâ€™s quite complex Swift code. An alternative, less Swifty code would be:

``````var counts: [Int] = []
for day in days {
var countForDay = 0
for exerciseDay in exercisesForWeek {
if exerciseDay.date.yearMonthDay == day.yearMonthDay {
countForDay = exerciseDay.exercises.count
}
}
counts.append(countForDay)
}
``````

This code is perfectly acceptable. However, variables rather than constants are inherently unsafe, as at any time you can write to `counts`. In a longer piece of code, you might not pick up that you are writing to `counts` when youâ€™re not supposed to.

Thatâ€™s why `let counts = days.map...` is preferred to the `for` loop and appending to `counts`.

I hope that helps - if youâ€™re still confused, please ask further questions.

2 Likes

@supernova2108 Please definitely check out the following Swift tutorials when you actually get a chance in order to understand even better how both `map(_:)` and `filter(_:)` really work under the hood after all:

I really do hope they help!

1 Like