Kotlin - How to apply modulo operation on each element of a matrix?

Viewed 335

I find Lambda in Kotlin to be very confusing and on the top of it is "it". There are two things I know about "it" and i.e.

  • If your Lambda has their own argument, you can replace its name with "it".
  • "It" is an automatically generated name for your Lambda, if it has only one argument, and you don't specify a different argument name.

Still I don't understand what actually passes as "it".

For E.g. I wanted to apply modulo function on each element of a 3x3 matrix.

fun main(){
    var result = Array(3) {
        IntArray(3) { 3;2;4;6;7;9;12;11;23 }
    }

    result = Array(3){ IntArray(3) {it%2} }

    println(result.joinToString("\n") { it.joinToString(" ") })
}

Here I assumed that "it" takes each element of the matrix which is clearly not the case as my output was:

0 1 0
0 1 0
0 1 0

So can you please explain me how "it" works, what is happening here? and what would be the correct way to implement this program?

1 Answers

Your line

result = Array(3){ IntArray(3) {it%2} }

isn't doing anything to the original Array that result is pointing at. You are creating a brand new group of array objects by calling the Array and IntArray constructors.

The lambda that you pass to the IntArray constructor has an input parameter that represents the array index, and the return value of your lambda is what will be put into the array at that index. So in this case it is the array index, and your lambda is returning 0 and 1 for even and odd indices respectively.

You are also instantiating your array incorrectly to begin with. Your lambda that you pass to that IntArray constructor is throwing away a bunch of pointless Int values and then returning 23 for each item. So you've created a 3x3 matrix that is completely filled with the number 23.

The correct syntax for creating an array with explicit values is to use arrayOf or intArrayOf.

val result = arrayOf(
    intArrayOf(3, 2, 4),
    intArrayOf(6, 7, 9),
    intArrayOf(12, 11, 23)
)

To modify all the values of an array, you typically iterate the traditional way, not with a lambda:

for (innerArray in result) {
    for (i in innerArray.indices)
        innerArray[i] = innerArray[i] % 2
}

You were probably thinking of the map function, which lets you pass a lambda and returns a new List with the lambda function applied to every element of the input collection. Or when working with collections other than arrays, you can use forEach or onEach to iterate them without modifying them.

Related