Scala-lambda参数可以匹配元组吗?

Scala-lambda参数可以匹配元组吗?,scala,Scala,比如说我有一些清单 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,而不是使用这个中间项变量 下面这样的内容是理想的,但是eclipse告诉

比如说我有一些清单

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,而不是使用这个中间
变量

下面这样的内容是理想的,但是eclipse告诉我
参数的数量错误;预期为1

val m = l.filter( (n, s) => n != 2 )

任何帮助都将不胜感激-使用2.9.0.1这是您能获得的最接近的帮助:

 val m = l.filter { case (n, s) => n != 2 }

它基本上是匿名数据库中的模式匹配语法。在
函数
对象和特征中也有
元组
方法,但它们只是这个模式匹配表达式的包装。

有很多选项:

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
(x)的

l、 过滤器{case(n,s)=>n!=2}
l、 unzip.zipped.map((n,s)=>n!=2).zip//抱怨zip已被弃用

嗯,尽管Kipton有一个很好的答案。实际上,你可以通过这样做来缩短它

val l = List((1, "blue"), (5, "red"), (2, "green"))
val m = l.filter(_._1 != 2)

我也考虑过同样的问题,今天来问你的问题

我不太喜欢部分函数方法(任何有
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)
也许这会很有用。
unTuple
对象自然应该放在某个工具名称空间中

增编:

适用于您的情况:

val m = l.filter( unTuple( (n:Int,color:String) =>
    n != 2
))
…是类型不匹配,因为lambda定义了

  • Function2[String,Int,Boolean]
    具有两个参数,而不是
  • Function1[(String,Int),Boolean]
    ,其中一个
    Tuple2[String,Int]
    作为其参数
您可以这样在它们之间进行转换:

val m = l.filter( ((n, s) => n != 2).tupled )

你可以用
\uu
替换
s
,因为它从未被使用过。越短越好。这对于非常琐碎的例子来说是有意义的,但对于更复杂的东西,Kipton的例子将产生更可读的代码。我对此投了反对票(5年后)因为它实际上并没有回答我的问题。我的问题是如何解包一个元组,而不是如何筛选一个列表。我认为这里有两个答案是有帮助的。我认为这种方法更适合于简单的情况。即使它没有回答实际的问题,登陆这里的人可能不知道这一点。而被接受的答案当然是直接的回答这个问题。
val m = l.filter( ((n, s) => n != 2).tupled )