使用给定的零件尺寸列表将Scala列表分成多个零件。[分区]

时间:2018-07-14 04:40:43

标签: scala list collections

我有两个列表:

val list1:List[Int]   =  List(5, 2, 6)

val list2:List[Any]  =  List("a", "b", "c", "d", "e", "f", "g", "h", "i", "j","k")

使得list1.sum >= list2.size

  

我想要一个由list2中的元素连续形成的列表的列表   带有list1中提到的尺寸。

例如:

如果list1是List(5,2,4),我想要的结果是:

List(List("a", "b", "c", "d", "e"),List("f", "g"),List("h", "i", "j","k"))

如果list1是List(5,4,6),我想要的结果是:

List(List("a", "b", "c", "d", "e"),List("f", "g","h", "i"),List("j","k"))

如何用简洁的代码做到这一点。

4 个答案:

答案 0 :(得分:4)

list2变成Iterator,然后映射到list1

val itr = list2.iterator
list1.map(itr.take(_).toList)
//res0: List[List[Any]] = List(List(a, b, c, d, e), List(f, g), List(h, i, j, k))

更新: 虽然这似乎可以达到预期的效果,但在其他地方也指出,重用迭代器实际上是不安全的,不能保证其行为。

通过一些修改,可以获得更安全的版本。

val itr = list2.iterator
list1.map(List.fill(_)(if (itr.hasNext) Some(itr.next) else None).flatten)

-或-

import util.Try
val itr = list2.iterator
list1.map(List.fill(_)(Try(itr.next).toOption).flatten)

答案 1 :(得分:1)

您可以根据从list2获得的尺寸在list1上切片,

  def main(args: Array[String]): Unit = {

    val groupingList: List[Int] = List(5, 2, 4)
    val data = List("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k")

    //0, 5
    //5, (5 + 2)
    //5 + 2, (5 + 2 + 4)

    val grouped = groupingList.zipWithIndex.map { case (_, index) =>
      val start = groupingList.slice(0, index).sum
      val end = groupingList.slice(0, index + 1).sum

      data.slice(start, end)
    }

    println(grouped)
  }

结果: List(List(a, b, c, d, e), List(f, g), List(h, i, j, k))

另请参阅:How slice works

答案 2 :(得分:1)

我喜欢用ex展示它 list1 = List(“一个”,“两个”,“三个”) List [String] =列表(一个,两个,三个)

list2 =列表(“红色”,“绿色”,“蓝色”) List [String] =列表(红色,绿色,蓝色)

list1 :: list2 列表[java.io.Serializable] =列表(列表(一,二,三),红色,绿色,蓝色)

var listSum = list1 :: list2 列表[java.io.Serializable] =列表(列表(一,二,三),红色,绿色,蓝色)

listSum 列表[java.io.Serializable] =列表(列表(一,二,三),红色,绿色,蓝色)

我们可以“ ::”将一个列表插入Scala中的另一个列表

答案 3 :(得分:0)

我发现,即使下面的代码也可以工作,但是jwvh发布的代码看上去比这更简洁,并且我理解在以下代码中将list1设置为Vector对于元素访问的性能更有意义:

list1.scan(0)(_+_).sliding(2).toList.map(x=>list2.drop(x(0)).take(x(1)-x(0)))

list1.scan(0)(_+_).zip(list1).map(x=>list2.drop(x._1).take(x._2))

list1.scan(0)(_+_).sliding(2).map(x=>list2.slice(x(0),x(1))).toList