Scala 将未知长度的 List 转换为 Tuple,因此将其传递给 Slick map 子句
Scala convert List with unknown length to Tuple so pass it to Slick map clause
我在 scala 代码中有 List
,例如我可以从特定方法接收,并且此列表的长度可能会不时变化,我的目标是将此 List
转换为 Tuple
具有相同的元素计数:
val lst = someComputationHere()
val tupleLst = lstToTuple(lst)
澄清
//if lst.length = 2 --> Tuple2
//if lst.length = 3 --> Tuple3
//if lst.length = 4 --> Tuple4
...............
//if lst.length = N --> TupleN
and so on
p.s。我宁愿不使用反射来解决这个问题
UPD
我的目标是将具有上述属性的传递列表传递给 Slick
map clause
。让我们考虑下一个代码快照:
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
转换为 Tuple
有 N 个元素
通常你不能这样做,因为元组访问方法 _1
、_2
等有编译时检查(列表大小在编译时未定义)。但是所有的元组都实现了Product trait,在这里你可以通过它的顺序获取元素:
(1, 2, 3).productElement(2) // returns 2
你可以尝试用下一个签名写方法(也许使用宏)
List[T] => Product
方法将是 return 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 类型。但这一切都显得很肮脏。
我不了解 Slick,但如果它只处理元组,对我来说似乎是一个糟糕的设计选择。即使在 Scala 2.12 中也没有为元数大于 22 的元组预定义类型,尽管 Scala 会综合创建它们。所以你最好的选择是一个大模式匹配,包括你需要支持的所有参数:
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)
...
}
我在 scala 代码中有 List
,例如我可以从特定方法接收,并且此列表的长度可能会不时变化,我的目标是将此 List
转换为 Tuple
具有相同的元素计数:
val lst = someComputationHere()
val tupleLst = lstToTuple(lst)
澄清
//if lst.length = 2 --> Tuple2
//if lst.length = 3 --> Tuple3
//if lst.length = 4 --> Tuple4
...............
//if lst.length = N --> TupleN
and so on
p.s。我宁愿不使用反射来解决这个问题
UPD
我的目标是将具有上述属性的传递列表传递给 Slick
map clause
。让我们考虑下一个代码快照:
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
转换为 Tuple
有 N 个元素
通常你不能这样做,因为元组访问方法 _1
、_2
等有编译时检查(列表大小在编译时未定义)。但是所有的元组都实现了Product trait,在这里你可以通过它的顺序获取元素:
(1, 2, 3).productElement(2) // returns 2
你可以尝试用下一个签名写方法(也许使用宏)
List[T] => Product
方法将是 return 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 类型。但这一切都显得很肮脏。
我不了解 Slick,但如果它只处理元组,对我来说似乎是一个糟糕的设计选择。即使在 Scala 2.12 中也没有为元数大于 22 的元组预定义类型,尽管 Scala 会综合创建它们。所以你最好的选择是一个大模式匹配,包括你需要支持的所有参数:
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)
...
}