我在scala代码中有List
,例如我可以从特定方法接收,此列表的长度可能会不时变化,我的目标是将此List
转换为{{1}具有相同的元素数:
Tuple
澄清
val lst = someComputationHere()
val tupleLst = lstToTuple(lst)
P.S。我宁愿不使用反射解决这个问题
UPD
我的目标是带有上述属性的通过列表,发送到//if lst.length = 2 --> Tuple2
//if lst.length = 3 --> Tuple3
//if lst.length = 4 --> Tuple4
...............
//if lst.length = N --> TupleN
and so on
Slick
。让我们考虑下一个代码快照:
map clause
此值的数量是dinamic,我将此query.map{ p=> (p.value1, p.value2, ... , p.valueN)}
引入列表:
values
问题描述: val lst = someComputationHere()
val tuples = toTuples(lst)//Problem is here
query.map{_ => tuples}
- 没有通过列表,作为后果,我必须将query.map{}
的长度N更改为lst
有N个元素
答案 0 :(得分:2)
我不知道Slick,但如果它只处理元组,那对我来说似乎是一个糟糕的设计选择。即使在Scala 2.12中,对于大于22的arity元组也没有预定义类型,尽管Scala将合成创建它们。所以你最好的选择是一个大模式匹配,包括你需要支持的所有arities:
def toTuple[A](lst: List[A]): Product = lst match {
case _1 :: Nil => Tuple1(_1)
case _1 :: _2 :: Nil => Tuple2(_1, _2)
case _1 :: _2 :: _3 :: Nil => Tuple3(_1, _2, _3)
...
}
答案 1 :(得分:0)
通常,您无法执行此操作,因为元组访问方法_1
,_2
等具有编译时检查(列表大小在编译时未定义)。但是所有元组都实现了Product trait,你可以按顺序获取元素:
(1, 2, 3).productElement(2) // returns 2
您可以尝试使用下一个签名(可能使用宏)编写方法
List[T] => Product
方法将返回TupleN
,其中N是列表大小。例如,非常原始的实现:
list.length match {
case 1 => (list(0))
case 2 => (list(0), list(1))
...
case 22 => (list(0), list(1), ... ,list(21))
case _ => throw some exception...
}
在运行时之后,您可以尝试将产品转换为具体的TupleN类型。但这一切看起来都很脏。