2013-04-10 40 views
2

我想多个列表转换,每一个恒定的内部列表的大小,看起来像这样:如何将List [List [Int]]的内部元素转换为tupleNs? (如何扁平化多态性tupleNs)

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和列表[INT],所以根据需要我无法打开(1, List(2,3))(1,2,3)

那么,我该如何扩展flatten函数来做到这一点,或者是否有更好的方法在scala中实现这一点? scalaz可以帮助吗?

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

+4

有毛病'名单(名单(1,2,3)){映射表的情况下( a,b,c)=>(a,b,c)}?一般是困难的,因为在编译时列表的长度是未知的。也许你可以使用不成形的''HList' – sschaef 2013-04-10 23:25:00

+1

可能有可能做一些有趣的无形,但它是否值得或不相符(相对于上面的@ sschaef的建议)很大程度上取决于你想要对结果做什么以及是否或者不是你真的需要多态性而不是arity。那么你能告诉我们一些情况吗? – 2013-04-11 08:12:03

+0

你说得对。我认为这很有趣,可能有一个简单的方法,但我猜不是。我甚至不确定为什么我首先想要元组,而不是逻辑选择列表。谢谢。 – flubba 2013-04-12 22:58:33

回答

1

您可以使用implicits做类似的东西:

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,这是恕我直言,而不是语法限制,因为你不能给出一种类型并告诉编译器推断其他类型。

UPDATE

,如果你在暗示传递明确看起来几乎更好:

list2tup(List(List(1,2),List(2,3)))(tup2ops)