使用JodaTime,尝试将List [LocalDate]转换为Tuple2 [JodaTime,JodaTime],这样我可以像这样进行多重分配:
val(expire, now) =
List(row.expireDate, new JodaDate) zip (_.toDateTimeAtStartOfDay.getMillis)
当然不编译。是否有类似简洁的方法来做上述事情?我知道我可以手动完成:
val(expire, now) =
(row.expireDate.toDateTimeAtStartOfDay.getMillis,
new JodaDate().toDateTimeAtStartOfDay.getMillis)
但这有点难看
答案 0 :(得分:10)
val Seq(expire, now) =
Seq(row.expireDate, new JodaDate).map(_.toDateTimeAtStartOfDay.getMillis)
答案 1 :(得分:4)
对于元组(不在标准库中),您想要的(假设您不想转换到 - Seq
路由)是Scalaz's Bifunctor
instance。有了它,您可以写下以下内容:
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> val cap = (_: String).toUpperCase
cap: String => java.lang.String = <function1>
scala> val removeLs = (_: String).replaceAll("l", "")
removeLs: String => java.lang.String = <function1>
scala> cap <-: ("hello", "world") :-> removeLs
res0: (java.lang.String, java.lang.String) = (HELLO,word)
或者,在您的情况下:
val f = (_: JodaDate).toDateTimeAtStartOfDay.getMillis
val (expire, now) = f <-: (row.expireDate, new JodaDate) :-> f
答案 2 :(得分:2)
val Seq(a, b) =
Seq("a", "b").map(_.toUpperCase)
println("a, b = %s, %s".format(a, b)) // a, b = A, B
答案 3 :(得分:1)
如果你想保持使用元组的类型安全(记住,当取消应用Seq
时,编译器将不检查长度),你可以编写一个包装器来添加标准中没有的函数库,它可以让你映射一个元组。
如果使用单个函数映射两个元素,因为Tuple2[A, B]
有两个类型参数,使这项工作的关键是要求A
和B
的证据是相同的类型。为此,需要一个B =:= A
类型的隐式参数;如果类型确实相等,编译器将提供类型为B => A
的函数。
class Tuple2Wrapper[A, B](t: (A, B)) {
def bimap[C, D](f: A => C, g: B => D): (C, D) = (f(t._1), g(t._2))
def <-:->[C](f: A => C)(implicit ev: B =:= A): (C, C) = bimap(f, f compose ev)
}
implicit def tuple2Tuple2Wrapper[A, B](t: (A, B)) = new Tuple2Wrapper(t)
scala> (1, 1) <-:-> (_ + 1)
res1: (Int, Int) = (2,2)
如果按照Scalaz的Tuple2
特征实现,可以采用更通用,更有用的方式(仅适用于Bifunctor
以外的更多类型)。