简体   繁体   中英

How to I modify arrays inside of a map in Kotlin

I am working with a map with strings as keys and arrays as values. I would like to adjust the map to be the original strings and change the arrays to the average values.

The original map is:

val appRatings = mapOf(
            "Calendar Pro" to arrayOf(1, 5, 5, 4, 2, 1, 5, 4),
            "The Messenger" to arrayOf(5, 4, 2, 5, 4, 1, 1, 2),
            "Socialise" to arrayOf(2, 1, 2, 2, 1, 2, 4, 2)
    )

What I have tried to do is:

val averageRatings = appRatings.forEach{ (k,v) -> v.reduce { acc, i -> acc + 1 }/v.size}

However this returns a Unit instead of a map in Kotlin. What am I doing wrong? I am working through a lambda assignment and they want us to use foreach and reduce to get the answer.

You can use forEach and reduce , but it's overkill, because you can just use mapValues and take the average:

val appRatings = mapOf(
    "Calendar Pro" to arrayOf(1, 5, 5, 4, 2, 1, 5, 4),
    "The Messenger" to arrayOf(5, 4, 2, 5, 4, 1, 1, 2),
    "Socialise" to arrayOf(2, 1, 2, 2, 1, 2, 4, 2)
)

val averages = appRatings.mapValues { (_, v) -> v.average() }

println(averages)

Output:

{Calendar Pro=3.375, The Messenger=3.0, Socialise=2.0}

You can do this with mapValues function:

val appRatings = mapOf(
        "Calendar Pro" to arrayOf(1, 5, 5, 4, 2, 1, 5, 4),
        "The Messenger" to arrayOf(5, 4, 2, 5, 4, 1, 1, 2),
        "Socialise" to arrayOf(2, 1, 2, 2, 1, 2, 4, 2)
    )

    val ratingsAverage = appRatings.mapValues { it.value.average() }

You already got some answers (including literally from JetBrains?? nice) but just to clear up the forEach thing:

forEach is a "do something with each item" function that returns nothing (well, Unit ) - it's terminal, the last thing you can do in a chain, because it doesn't return a value to do anything else with. It's basically a for loop, and it's about side effects, not transforming the collection that was passed in and producing different data.

onEach is similar, except it returns the original item - so you call onEach on a collection, you get the same collection as a result. So this one isn't terminal, and you can pop it in a function chain to do something with the current set of values, without altering them.

map is your standard "transform items into other items" function - if you want to put a collection in and get a different collection out (like transforming arrays of Ints into single Int averages) then you want map . (The name comes from mapping values onto other values, translating them - which is why you always get the same number of items out as you put in)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM