组合多个任意长度的列表

Th *_*Ä s 14 scala scala-collections

我正在寻找以下列方式加入多个列表的方法:

ListA a b c
ListB 1 2 3 4
ListC + # * § %
..
..
..

Resulting List: a 1 + b 2 # c 3 * 4 § %
Run Code Online (Sandbox Code Playgroud)

单词:按顺序排列的元素,从第一个列表开始合并到结果列表中.任意数量的输入列表的长度可以不同.

我使用了zip的变体,滑动迭代器的多种方法但没有工作,特别是处理不同的列表长度.在scala中必须有一种优雅的方式;)

Lui*_*hys 20

val lists = List(ListA, ListB, ListC)

lists.flatMap(_.zipWithIndex).sortBy(_._2).map(_._1)
Run Code Online (Sandbox Code Playgroud)

这是非常不言自明的.它只是将每个值与其各自列表中的位置进行拉链,按索引排序,然后将值拉回.

  • @Miles是的,它推迟到`java.util.Arrays.sort`,并引用javadocs:"这种类型保证是稳定的:相同的元素不会因排序而重新排序." (2认同)

joe*_*cii 5

我是这样做的:

class ListTests extends FunSuite {
  test("The three lists from his example") {
    val l1 = List("a", "b", "c")
    val l2 = List(1, 2, 3, 4)
    val l3 = List("+", "#", "*", "§", "%")

    // All lists together
    val l = List(l1, l2, l3)

    // Max length of a list (to pad the shorter ones)
    val maxLen = l.map(_.size).max

    // Wrap the elements in Option and pad with None
    val padded = l.map { list => list.map(Some(_)) ++ Stream.continually(None).take(maxLen - list.size) }

    // Transpose 
    val trans = padded.transpose

    // Flatten the lists then flatten the options
    val result = trans.flatten.flatten

    // Viola 
    assert(List("a", 1, "+", "b", 2, "#", "c", 3, "*", 4, "§", "%") === result)
  }
}
Run Code Online (Sandbox Code Playgroud)