Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Kotlin中将成对列表展平为列表的惯用方法_Kotlin - Fatal编程技术网

在Kotlin中将成对列表展平为列表的惯用方法

在Kotlin中将成对列表展平为列表的惯用方法,kotlin,Kotlin,标题应该很有解释性。我有列表,我想把它转换成列表,以惯用且(更重要的是)高效的方式包含所有对中的所有元素 我知道有,但这是针对List->List的情况 目前,我提出了两种实现作为扩展函数: fun <T> List<Pair<T, T>>.flatten(): List<T> { val accumulator = mutableListOf<T>() this.forEach { accumulato

标题应该很有解释性。我有
列表
,我想把它转换成
列表
,以惯用且(更重要的是)高效的方式包含所有对中的所有元素

我知道有,但这是针对
List
->
List
的情况

目前,我提出了两种实现作为扩展函数:

fun <T> List<Pair<T, T>>.flatten(): List<T> {
    val accumulator = mutableListOf<T>()
    this.forEach {
        accumulator.add(it.first)
        accumulator.add(it.second)
    }
    return accumulator
}
fun List.flatte():List{
val累加器=mutableListOf()
这是forEach{
累加器。添加(it.first)
累加器。添加(它。秒)
}
回流蓄能器
}

fun List.flatt2():List{
返回这个.fold(mutableListOf()){累加器:MutableList,pair:pair->
累加器。添加(对。第一个)
累加器。添加(第二对)
累加器
}
}
但它们看起来并不优雅


它能做得更好吗(在可读性、效率和惯用性方面)?

我能想到的最优雅的方法是使用,这是
展平的一种更普遍的形式-在展平之前做一张
地图

fun <T> List<Pair<T, T>>.flattenPairs(): List<T> =
        this.flatMap { (x, y) -> listOf(x, y) }
fun List.flattPairs():List=
this.flatMap{(x,y)->listOf(x,y)}
不过,这可能比您的解决方案效率低,因为它会创建许多中间列表。如果您想避免这种情况,您最后的尝试可以像下面这样进行清理:

fun <T> List<Pair<T, T>>.flatten2(): List<T> =
    this.fold(mutableListOf()) { accumulator, (x, y) ->
        accumulator.apply {
            add(x)
            add(y)
        }
    }
fun List.flatt2():List=
this.fold(mutableListOf()){acculator,(x,y)->
累加器。应用{
加(x)
加(y)
}
}
  • lambda参数上的类型注释不是必需的
  • 这对可以被解构
  • 使用
    apply
    作用域功能减少重复的单词
    累加器
  • 已更改为表达式体

我认为您的两种解决方案都非常可读,因此不需要太多改进

就效率而言,在这种情况下,循环始终是最好的,尽管您应该预先分配列表的大小以进一步优化它:

val accumulator = ArrayList<T>(size * 2)
val累加器=数组列表(大小*2)

就其惯用性而言,我真的认为对于一个简单的扩展函数,它不需要比这个更好。最明显的方法是使用另一个答案提到的
flatMap
,但是在我看来,这会使它在不需要的时候效率大大降低。在这两个选项中,第二个选项更为惯用,性能应该相同,因此请根据您的喜好选择。

这个
.flattPairs()
非常紧凑,我必须记住,在另一个效率不那么重要的时候。另外,感谢您提供的提示
.flatt2()
现在看起来好多了:)从您的问题来看,效率或惯用语对您来说是否更重要还不清楚,所以我尝试从这两个方面进行阐述。那么最后,你是否更关心效率@asikorski是的,在这两种情况中,效率更重要。@asikorski在这种情况下指定数组列表的初始容量,就像Henry Twist的答案一样。除此之外,我想不出还有什么显著的改进。谢谢你的建议和预分配!使用具体的实现(
ArrayList
这里)有什么缺点吗?好吧,在某个地方必须有一个具体的实现,事实上,如果您查看
mutableListOf
的源代码,它无论如何都会创建一个
ArrayList
。使用Kotlin函数的唯一好处是,将来他们可能会推荐一种比
ArrayList
更有效的实现,并且
mutableListOf
函数将被更新以反映它。但是,通常情况下不会,而且由于
ArrayList
ArrayList
支持,它通常是大多数情况下的最佳选择。与像
LinkedList这样的东西相比,它唯一的缺点是,当容量用完时,它必须增长,但是当预分配这个问题不是一个因素时。
val accumulator = ArrayList<T>(size * 2)