如何在Kotlin中按块映射列表

时间:2019-02-01 15:41:03

标签: kotlin

我经常以诸如以下的数据源结尾(下面的伪代码,没有任何特定的语法,只是为了说明):

list = {
  "XLabel", 
  "XDescription", 
  "YLabel", 
  "YDescription", 
  "ZLabel", 
  "ZDescription"
}

所需的输出是:

list = { 
  MyClass("XLabel", "XDescription"), 
  MyClass("YLabel", "YDescription"), 
  MyClass("ZLabel", "ZDescription")
}

除了做fold()并将其折叠到新列表之外,还有什么更干净的方法了吗?我也拒绝做类似list.partition().zip()

的事情

我基本上希望有一个功能更强大的mapmapChunks( it1, it2 -> MyClass(it1, it2))一样工作,其中分块是函数的一部分,因此变得容易又好用。 (我的示例中的列表以两个为大块,但是3也是一个流行的用例。)

此功能存在吗?还是最惯用的方法是什么?

5 个答案:

答案 0 :(得分:4)

您可以使用chunked函数,然后在结果上使用map。如果您分解lambda参数,语法将非常接近您想要的语法:

list.chunked(2)
    .map { (it1, it2) -> MyClass(it1, it2) }
    // Or use _it_ directly: .map { MyClass(it[0], it[1]) }

答案 1 :(得分:0)

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/chunked.html

Chunked返回您指定大小的子列表

这是您想要的API调用

考虑您的清单是2人成对的,您可以这样做

list.chunked(2)  //List<List<String>>
    .map{MyClass(it[0], it[1]} //list<MyClass>

答案 2 :(得分:0)

我认为windowed方法应该做您想要的。

lst.windowed(size = 2, partialWindows = false) { innerList -> MyClass(innerList[0], innerList[1]) }

您也可以使用chunked,但它会在后台调用windowed。但是通过分块,您可以获得的元素比预期少的列表

答案 3 :(得分:0)

您可以创建一个扩展功能,例如mapChunks,然后重新使用它:

fun List<String>.mapChunks(): List<MyClass> {
    return chunked(2).map { MyClass(it[0], it[1]) }
}

val list1 = listOf(
    "XLabel",
    "XDescription",
    "YLabel",
    "YDescription",
    "ZLabel",
    "ZDescription"
)
val result1 = list1.mapChunks()

val list2 = listOf(
        "XLabel1",
        "XDescription1",
        "YLabel1",
        "YDescription1",
        "ZLabel1",
        "ZDescription1"
)
val result2 = list2.mapChunks()

答案 4 :(得分:0)

要添加到现有答案中,可以使用chunked函数,并将lambda转换作为第二个参数传递:

list.chunked(2) { (label, description) -> MyClass(label, description) }

这种方式效率更高,因为两个元素的临时列表可在所有块中重用。