I had the following code snippet and somehow i got it working . However, I didnt understand how these lines work
val x = List.range(1, 10)
val evens1 = x.filter((i: Int) => i % 2 == 0) // I understand this , closure is passed as a function variable to filter function
val isEven = (i: Int) => i % 2 == 0
val evens = x.filter(i =>isEven(i)) // this is working, but i didnt understand this
val evens1 = x.filter(isEven(i))//why this is not working, how we can make this work
val evens2 = x.filter(isEven)//this works
CodePudding user response:
So for all cases remember that filter
is a method on List
which accepts a function as an argument.
val evens = x.filter((i: Int) => i % 2 == 0)
This is creating a function using the lambda syntax.
PS: This can be simplified as:
val evens = x.filter(i => i % 2 == 0)
// No need to provide the type of i, it is inferred by the context.
You may even simplify it even more like this:
val evens = x.filter(_ % 2 == 0)
// No need to name the parameter if it is only used once.
But I personally don't recommend abusing the _
syntax, since it can be confusing.
val isEven = (i: Int) => i % 2 == 0
This creates a function using the lambda syntax and stores it in the isEven
variable.
val evens = x.filter(i => isEven(i))
This is exactly the same as the first one; a lambda. Which is this case is redundant since the body of the lambda is just a function call.
That is why you can also do this:
val evens = x.filter(isEven)
Finally, this:
val evens1 = x.filter(isEven(i))
Won't work, since this is a compile error because there is no variable i
defined anywhere; and even if there would be one then this would fail since filter
expects an Int => Boolean
and isEven(i)
would return a plain Boolean
how we can make this work
Is not possible to make this to work since what you want is not valid syntax.
...
Well, you may do this:
val evens = x.filter(isEven(_))
// Which would be equivalent to:
val evens = x.filter(i => isEven(i))
Or maybe you may do something like this:
def createPredicateEqualsTo(to: Int): Int => Boolean =
i => i == to
val allTwos = x.filter(createPredicateEqualsTo(2))
But, this is way different to what you had since now I have a method that returns a function and I am calling it with a constant to create a predicate which will be passed down to filter