16

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?

9
  • You need to assign this array to another array. Commented May 22, 2018 at 10:26
  • I don''t want to do that , how do i modify the existing array? Commented May 22, 2018 at 10:27
  • Change the val someArray to var someArray. Then someArray = someArray.map({num -> num*2}) Commented May 22, 2018 at 10:28
  • Ok , is there any in which i can modify it without assiging it? Commented May 22, 2018 at 10:36
  • Yes! Change the val to var to make it mutable. Then assign the result of the map to the same variable. That's what I meant in the previous comment. Commented May 22, 2018 at 10:38

4 Answers 4

14

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) { ... }
Sign up to request clarification or add additional context in comments.

Comments

10

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 , ") }
}

1 Comment

Ok , is there any in which i can modify it without creating a new variable?
6

An alternative is to use forEachIndexed instead of map. Replace

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

by

someArray.forEachIndexed{ index, num -> someArray[index] = num * 2 }    

Comments

2

As many have stated, the map returns a new list and doesn't modify the original.

The most efficient way to rewrite your intended code is to do

// assuming you want to act upon individual elements in the list
fun main(args : Array<String>) {
    val someArray : Array<Int> =  arrayOf(3,53,2,521,51,23,512,34,124);
    println("Original array is $someArray")
    someArray
        .map { it * 2 }
        .forEach { print("$it , ") }
}

or if you just want to see the comma separated list of values

// really just want to print the transformed values instead
fun main(args : Array<String>) {
    val someArray : Array<Int> =  arrayOf(3,53,2,521,51,23,512,34,124);
    println("Original array is $someArray")
    someArray
        .map { it * 2 }
        .also { print(it.joinToString()) }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.