【问题标题】:How to apply map function to array in Kotlin and change its values?如何将 map 函数应用于 Kotlin 中的数组并更改其值?
【发布时间】:2018-05-22 10:21:40
【问题描述】:

我正在使用此代码。

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

但地图功能似乎不起作用。这是它打印的内容

原始数组是 3 , 53 , 2 , 521 , 51 , 23 , 512 , 34 , 124 , 修改后的数组为

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

我的问题是为什么数组没有将其元素的值加倍?我在这里错过了什么?

【问题讨论】:

  • 您需要将此数组分配给另一个数组。
  • 我不想那样做,如何修改现有数组?
  • val someArray 更改为var someArray。然后someArray = someArray.map({num -&gt; num*2})
  • 好的,有没有我可以在不分配的情况下修改它?
  • 是的!将 val 更改为 var 以使其可变。然后将映射的结果分配给同一个变量。这就是我在上一条评论中的意思。

标签: arrays kotlin


【解决方案1】:

您始终可以定义自己的扩展来满足您的需要:

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

用法如下所示:

someArray.mapInPlace { num -> num * 2 }

请注意,原始数组有一些特殊的非泛型类,例如IntArray(另请参阅this question),因此您可能应该使用它们而不是泛型类。当然,您必须分别为它们中的每一个定义此扩展,例如:

fun IntArray.mapInPlace(transform: (Int) -> Int) { ... }
fun DoubleArray.mapInPlace(transform: (Double) -> Double) { ... }

【讨论】:

    【解决方案2】:

    根据文档,map 不会修改现有项目,而是返回一个 List,其中包含应用于所有项目的映射函数的结果:

    返回一个列表,其中包含将给定变换函数应用于原始数组[或集合或映射,取决于接收者]中的每个元素的结果。

    因此,要获得预期的结果,您应该执行以下操作:

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

    编辑

    据我所知没有内置函数可让您就地映射项目。但是,在您的情况下,您正在处理 Array,它是一个可变数据结构,因此替代方法是使用旧式循环来迭代转换其项目(您可以使用 MutableList 或应用相同的逻辑其他使用Iterator 更新值的可变数据结构)。像这样的:

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

    【讨论】:

    • 好的,有没有我可以在不创建新变量的情况下修改它?
    【解决方案3】:

    另一种方法是使用forEachIndexed 而不是map。替换

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

    通过

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

    【讨论】:

      【解决方案4】:

      正如许多人所说,地图会返回一个新列表并且不会修改原始列表。

      重写你想要的代码最有效的方法是做

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

      或者如果您只想查看逗号分隔的值列表

      // 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()) }
      }
      

      【讨论】:

        猜你喜欢
        • 2020-05-23
        • 2020-09-16
        • 1970-01-01
        • 2020-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-26
        相关资源
        最近更新 更多