2

我想转换多个列表,每个列表都有一个恒定的内部列表大小,如下所示:

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

对此:

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

因此,如果val q: List[List[Int]] = List(List(1, 2, 3), List(3, 4, 5),可以尝试以下方法:

    q.map(_.collect { case a :: b => (a,b) })

对于 3 元素列表示例,这为您提供了以下形式的内容:

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

我不能展平元组,因为它们包含两种类型:Int 和 List[Int],所以我不能按需要(1, List(2,3))变成(1,2,3)

那么,我该如何扩展 flatten 函数来做到这一点,或者有没有更好的方法在 scala 中完成这个?scalaz 能帮上忙吗?

tl;dr:如何将列表的内部列表转换为元组?(可能的广义问题:如何展平多态元组?)

4

1 回答 1

1

你可以使用隐式来做类似的事情:

trait TupOps[T,I] {
  val size: Int
  def fromList(vals: List[I]): T
}

def list2tup[T,I](vals: List[List[I]])(implicit to: TupOps[T,I]) = {
  if (!vals.forall(_.size == to.size)) sys.error("wrong list size")
  else vals.map(to.fromList _)
}

implicit def tup2ops[I] = new TupOps[(I,I),I] {
  val size = 2
  def fromList(v: List[I]) = (v(0), v(1))
}

implicit def tup3ops[I] = new TupOps[(I,I,I),I] {
  val size = 3
  def fromList(v: List[I]) = (v(0), v(1), v(2))
}

像这样调用:

list2tup[(Int,Int),Int](List(List(1,2),List(2,3)))

但这不一定更好,特别是因为您必须Int第二次编写,恕我直言,这是一种语法限制,因为您不能给出一种类型并告诉编译器推断另一种类型。

更新

如果你显式地传入隐式,它看起来几乎更好:

list2tup(List(List(1,2),List(2,3)))(tup2ops)
于 2013-04-10T23:51:19.127 回答