【问题标题】:Split a scala list into n interleaving lists将 scala 列表拆分为 n 个交错列表
【发布时间】:2012-06-21 06:36:50
【问题描述】:

给定一个List 比如

List(1, 2, 3, 4, 5, 6, 7)

将其拆分为 n 个子列表并以循环方式将项目放入每个列表的最佳方法是什么?

例如如果 n = 3,结果应该是

List(List(1, 4, 7), List(2, 5), List(3, 6))

我认为集合 API 中有一个方法可以做到这一点,但我似乎找不到它。

优雅单线的奖励积分 ;)

【问题讨论】:

标签: scala scala-collections


【解决方案1】:
scala> def round[T](l: List[T], n: Int) = (0 until n).map{ i => l.drop(i).sliding(1, n).flatten.toList }.toList
round: [T](l: List[T], n: Int)List[List[T]]

scala> round((1 to 7).toList, 3)
res4: List[List[Int]] = List(List(1, 4, 7), List(2, 5), List(3, 6))

【讨论】:

    【解决方案2】:

    这是一个简单的单行:

    scala> List.range(1, 10)
    res11: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
    scala> res11.grouped(3).toList.transpose
    res12: List[List[Int]] = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9))
    

    不幸的是,当您的列表不是可转置时,它将无法工作。

    scala> List.range(1, 8).grouped(3).toList.transpose
    java.lang.IllegalArgumentException: transpose requires all collections have the 
    same size
    

    您可以使用以下方法使其可转置,然后应用上述方法。

    scala> def extend[A](xs: List[A], c: Int): List[Option[A]] = {
         |   val n = Stream.iterate(c)(c +).find(_ >= xs.length).get
         |   xs.map(Some(_)).padTo(n, None)
         | }
    extend: [A](xs: List[A], c: Int)List[Option[A]]
    
    scala> List.range(1, 8)
    res13: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
    
    scala> extend(res13, 3).grouped(3).toList.transpose.map(_.flatten)
    res14: List[List[Int]] = List(List(1, 4, 7), List(2, 5), List(3, 6))
    

    放在一起:

    scala> def round[A](xs: List[A], c: Int) = {
         |   val n = Stream.iterate(c)(c +).find(_ >= xs.length).get
         |   val ys = xs.map(Some(_)).padTo(n, None)
         |   ys.grouped(c).toList.transpose.map(_.flatten)
         | }
    round: [A](xs: List[A], c: Int)List[List[A]]
    
    scala> round(List.range(1, 10), 3)
    res16: List[List[Int]] = List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9))
    
    scala> round(List.range(1, 8), 3)
    res17: List[List[Int]] = List(List(1, 4, 7), List(2, 5), List(3, 6))
    

    【讨论】:

    • ys.grouped(3) 是错字吗?
    • @senia,为什么会是错字?
    • @senia,哦,是的。谢谢。更正。
    • 你会得到OutOfMemoryErrorround(list, 0)
    • 是的,我知道这一点。该功能并非完全万无一失。
    【解决方案3】:

    如果你不关心让它循环,你可以这样做:

    val list = List(1, 2, 3, 4, 5, 6, 7)
    list.grouped(Math.ceil(list.size / 3))
    

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 2018-08-13
      • 1970-01-01
      • 2012-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-03-11
      • 2018-12-08
      相关资源
      最近更新 更多