I've got the task to write a function using fold (functional programming) to count the number of elements in a list that fulfill the predicate. I was given the function signature fun <A> count(list<A>, predicate: (A) -> Boolean): Int
. Fold shall not only be used as iteration, but also generate the return value. So I tried to do this:
fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
return list.fold(0) {
acc, a ->
if (predicate(a)) {
return acc + 1
}
return acc
}
}
I wrote a println to check if it works:
println(count3(listOf (1, -2, 3, 10, -5, 8, 12), { it > 0 && it < 10 }))
However, I got the result 1 instead of 3 on the console and I don't know where the fault is. So, does anyone have an idea where my error is or how I can implement the function instead?
And just to be clear: Fold accumulates a value, starting with the initial value (in this case 0) and applying the operation from left to right to the current accumulator and each element or am I mistaken?
EDIT (I hope it's okay to edit a question instead of asking a new one):
Is it possible to return a whole list instead of just an int? I just found examples returning integers or booleans. What I tried: I've used the same function signature from above. But instead of return an Int, I want to return a list:
fun <A> returnList(list: List<A>, predicate: (A) -> Boolean): List<A> {
return list.fold(mutableListOf()) {
acc, a ->
if (predicate(a)) {
acc.add(a)
} else {
acc
}
}
}
The problem that I found is that acc.add(a)
returns a boolean and not a list, so that the IDE marks it as a mistake. So is there a way to return a list?
Thanks in Advance.
By saying return
you return the entire count
function. you can use return@fold
instead. so like
fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
return list.fold(0) {
acc, a ->
if (predicate(a)) {
return@fold acc + 1
}
return@fold acc
}
}
alternatively and maybe better is to do it like this
fun <A> count(list: List<A>, predicate: (A) -> Boolean): Int {
return list.fold(0) {
acc, a ->
if (predicate(a)) {
acc + 1
} else {
acc
}
}
}
the last expression in a lambda is implicitly also its return value