【问题标题】:Divide list into two list将列表分成两个列表
【发布时间】:2023-02-03 19:54:52
【问题描述】:

有没有一种简单的方法可以将 Double 的列表分成 Kotlin 中的两个成对列表?

以这样的方式:

[x1, y1, x2, y2, x3, y3] => [(x1, x2), (x2, x3), (x3, x1)], [(y1, y2), (y2, y3), (y3, y1)] 

我尝试使用filterIndexedzipWithNext

val x = filterIndexed { index, _ -> index % 2 == 0 }.zipWithNext()
val y = filterIndexed { index, _ -> index % 2 == 1 }.zipWithNext()

但结果是:

[x1, y1, x2, y2, x3, y3] => [(x1, x2), (x2, x3)], [(y1, y2), (y2, y3)] 

【问题讨论】:

  • 看起来您只需将前两个元素复制到列表的末尾,此方法就可以使用。

标签: kotlin


【解决方案1】:

是的,您可以在 Kotlin 中将双打列表分成两个对列表。

val lst = listOf(x1, y1, x2, y2, x3, y3)
val list1 = lst.chunked(2).map { it[0] to it[1] }
val list2 = lst.drop(2).chunked(2).map { it[0] to it[1] } + listOf(lst[0] to lst[2])

chunked 方法用于将原始列表 lst 分成两个元素对。 map 函数用于从每个分块对创建一个新的对列表。第二个列表是通过使用 drop 方法跳过 lst 的前两个元素并重复该过程创建的。

这将产生两个成对列表,list1 和 list2。

【讨论】:

    【解决方案2】:

    如果我理解正确,您使用的 zipWithNext 的问题是它不会“环绕”,即输出最终的 (x3, x1) 或 (y3, y1) 对,其中包含最后一个和第一个元素的名单。

    您可以通过简单地声明您自己的 zipWithNext 版本来解决这个问题。

    你可以做这样的事情:

    fun <T> Iterable<T>.zipWithNextAndWrapAround(): List<Pair<T, T>> {
        val zippedWithNext = zipWithNext()
        if (zippedWithNext.isEmpty()) return zippedWithNext
        return zippedWithNext + (zippedWithNext.last().second to zippedWithNext.first().first)
    }
    

    或者复制粘贴zipWithNext的原始源码,稍作修改:

    fun <T> Iterable<T>.zipWithNextAndWrapAround(): List<Pair<T, T>> {
        val iterator = iterator()
        if (!iterator.hasNext()) return emptyList()
        val result = mutableListOf<Pair<T, T>>()
        var current = iterator.next()
    
        // remember what the first element was
        val first = current
        while (iterator.hasNext()) {
            val next = iterator.next()
            result.add(current to next)
            current = next
        }
    
        // at last, add this pair
        result.add(current to first)
        return result
    }
    

    用法:

    val x = list.filterIndexed { index, _ -> index % 2 == 0 }.zipWithNextAndWrapAround()
    val y = list.filterIndexed { index, _ -> index % 2 == 1 }.zipWithNextAndWrapAround()
    

    请注意,这是在列表中循环两次。您可以通过编写自己的 partition 版本(称为 partitionIndexed)来避免这种情况。

    【讨论】:

      猜你喜欢
      • 2013-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      相关资源
      最近更新 更多