I have complex logic in nested foreach loops that ...
# announcements
j
I have complex logic in nested foreach loops that is adding items to my collection. It smells that I need to call
list.add(item)
everywhere. (I will use simple example) I’ve tried to replace
Copy code
(0..3).forEach {
    list.add(it)
}
with
Copy code
list.add(
    (0..3).forEach {
        it
    }
)
However, it doesn’t compile. Is there a way to achieve it?
j
list.add
takes a single item. What you are looking for is probably `list.addAll`https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/add-all.html
s
Copy code
list.addAll(
    (0..3).map {
        it
    }
)
f
But note that the performance will be much worse because you build a range to build a list to add it to a list.
I added
buildList
(and friends) to Kotlin, should be available in the next patch release as experimental and non-experimental in the next minor release: https://github.com/JetBrains/kotlin/pull/2925
However, you always need to call
add
in order to add something. Nothing smells here, this is simply how it works.
j
I mean, my logic is much complex
Copy code
val items = mutableListOf<Item>()

        days.groupBy { it.date.year }.forEach { (year, daysOfYear) ->
            daysOfYear.groupBy { it.date.month }.forEach { (month, daysOfMonth) ->

                items.add(
                    MonthItem("MonthItem$year$month", daysOfMonth.first().date, month.title(), month.background())
                )

                daysOfMonth.groupBy { it.date.weekNumber() }.forEach { (week, daysOfWeek) ->

                    items.add(
                        WeekItem("WeekItem$year$month$week", daysOfWeek.first().date, formatDateRange(daysOfWeek.first().date, daysOfWeek.last().date))
                    )

                    if (daysOfWeek.flatMap { it.events }.isEmpty()) {
                        items.add(
                            CreateEventItem("CreateEventItem${daysOfWeek}", daysOfWeek[0].date)
                        )
                    } else {
                        daysOfWeek.forEach { day ->
                            if (day.events.isEmpty()) {
                                items.add(
                                    CreateEventItem("CreateEventItem${day}", day.date)
                                )
                            } else {
                                day.events.forEachIndexed { index, event ->
                                    items.add(
                                        EventItem("EventItem$day$event", day.date, event, index == 0)
                                    )
                                }
                            }
                        }
                    }
                }
            }
        }
Tbh, I have issues with using map in my case, I guess, will leave it as it is. Still more familiar with imperative style 😉
s
Im not sure any "functional" style would be more readable.
j
thank you for your perspective @spand Not gonna chase trends in that case 😉