所以说我有一些像
这样的清单val l = List((1, "blue"), (5, "red"), (2, "green"))
然后我想过滤其中一个,我可以做类似的事情
val m = l.filter(item => {
val (n, s) = item // "unpack" the tuple here
n != 2
}
有没有办法可以直接将元组“解包”为lambda的参数,而不是让这个中间item
变量?
像下面这样的东西是理想的,但是eclipse告诉我wrong number of parameters; expected=1
val m = l.filter( (n, s) => n != 2 )
任何帮助将不胜感激 - 使用2.9.0.1
答案 0 :(得分:78)
这是你能得到的最接近的地方:
val m = l.filter { case (n, s) => n != 2 }
它基本上是匿名PartialFunction内的模式匹配语法。 tupled
对象和特征中也有Function
个方法,但它们只是这个模式匹配表达式的包装。
答案 1 :(得分:18)
val l = List((1, "blue"), (5, "red"), (2, "green"))
val m = l.filter(_._1 != 2)
答案 2 :(得分:8)
有很多选择:
for (x <- l; (n,s) = x if (n != 2)) yield x
l.collect{ case x @ (n,s) if (n != 2) => x }
l.filter{ case (n,s) => n != 2 }
l.unzip.zipped.map((n,s) => n != 2).zip // Complains that zip is deprecated
答案 3 :(得分:5)
val m = l.filter( (n, s) => n != 2 )
...是类型不匹配,因为lambda定义了
Function2[String,Int,Boolean]
有两个参数而不是Function1[(String,Int),Boolean]
,其中一个Tuple2[String,Int]
作为参数。您可以像这样转换它们:
val m = l.filter( ((n, s) => n != 2).tupled )
答案 4 :(得分:0)
我思索过同样的问题,并于今天提出了你的问题。
我不太喜欢部分函数方法(任何具有case
的东西),因为它们意味着逻辑流可能有更多的入口点。至少在我看来,它们往往模糊了代码的意图。另一方面,我确实想直接去像你这样的元组字段。
这是我今天起草的解决方案。它似乎有效,但我还没有在生产中尝试过它。
object unTuple {
def apply[A, B, X](f: (A, B) => X): (Tuple2[A, B] => X) = {
(t: Tuple2[A, B]) => f(t._1, t._2)
}
def apply[A, B, C, X](f: (A, B, C) => X): (Tuple3[A, B, C] => X) = {
(t: Tuple3[A, B, C]) => f(t._1, t._2, t._3)
}
//...
}
val list = List( ("a",1), ("b",2) )
val list2 = List( ("a",1,true), ("b",2,false) )
list foreach unTuple( (k: String, v: Int) =>
println(k, v)
)
list2 foreach unTuple( (k: String, v: Int, b: Boolean) =>
println(k, v, b)
)
输出:
(a,1)
(b,2)
(a,1,true)
(b,2,false)
也许这证明是有用的。 {@ 1}}对象自然应放在某个工具命名空间中。
附录:
适用于您的案件:
unTuple