Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to apply map function to array in Kotlin and change its values?

Tags:

arrays

kotlin

I am working with this code.

fun main(args : Array<String>){

    val someArray : Array<Int> =  arrayOf(3,53,2,521,51,23,512,34,124);

    println("Original array is ")

    someArray.forEach {print("$it , ")}

    someArray.map({num -> num*2})

    println("Changed array is ")

    println()

    someArray.forEach { print("$it , ") }
}

But the map function does not seem to work. Here is what it prints

Original array is 3 , 53 , 2 , 521 , 51 , 23 , 512 , 34 , 124 , Changed array is

3 , 53 , 2 , 521 , 51 , 23 , 512 , 34 , 124 ,

My question is why is the array not doubling the value of its elements? What i am i missing here?

like image 343
Dishonered Avatar asked May 22 '18 10:05

Dishonered


2 Answers

From the documentation, map doesn't modify the items in place but rather returns a List containing the result of the mapping function applied to all the items:

Returns a list containing the results of applying the given transform function to each element in the original array [or collection or map, depending on the receiver].

So, to get the expected result you should do something like:

val doubled = someArray.map { n -> n * 2}
doubled.forEach { print("$it , ") }

EDIT

From what I know there's no built-in function allowing you to map items in-place. However, in your case you're dealing with an Array, which is a mutable data structure, so the alternative is to use an old-style loop to iteratively transform its items (you can apply the same logic with MutableList or other mutable data structures using an Iterator to update values). Something like this:

fun main(args: Array<String>) {
    val someArray: Array<Int> = arrayOf(3, 53, 2, 521, 51, 23, 512, 34, 124);

    someArray.forEach { print("$it , ") }

    println()

    for (i in 0 until someArray.size) {
        someArray[i] = someArray[i] * 2
    }

    someArray.forEach { print("$it , ") }
}
like image 124
user2340612 Avatar answered Nov 18 '22 10:11

user2340612


You could always define your own extension that does what you need:

fun <T> Array<T>.mapInPlace(transform: (T) -> T) {
    for (i in this.indices) {
        this[i] = transform(this[i])
    }
}

Usage would look like this:

someArray.mapInPlace { num -> num * 2 }

Note that there are special non-generic classes for primitive arrays, such as IntArray (see also this question), so you should probably be using those instead of the generic one. Of course then you'd have to define this extension for each of them separately, like:

fun IntArray.mapInPlace(transform: (Int) -> Int) { ... }
fun DoubleArray.mapInPlace(transform: (Double) -> Double) { ... }
like image 14
zsmb13 Avatar answered Nov 18 '22 11:11

zsmb13