我最近一直在研究Scala的初学者项目,并且有关于Scala列表的初学者问题。
假设我有一个元组列表(例如List[Tuple2[String, String]]
)。是否有一种方便的方法可以从List返回指定元组的第一个出现,或者是否需要手动遍历列表?
答案 0 :(得分:13)
scala> val list = List(("A", "B", 1), ("C", "D", 1), ("E", "F", 1), ("C", "D", 2), ("G", "H", 1)) list: List[(java.lang.String, java.lang.String, Int)] = List((A,B,1), (C,D,1), (E,F,1), (C,D,2), (G,H,1)) scala> list find {e => e._1 == "C" && e._2 == "D"} res0: Option[(java.lang.String, java.lang.String, Int)] = Some((C,D,1))
答案 1 :(得分:6)
您可以尝试使用find。 (更新了scala-doc的find位置)
答案 2 :(得分:3)
正如之前的评论所述,find
可能是最简单的方法。 Scala的集合中实际上有三种不同的“线性搜索”方法,每种方法返回的值略有不同。您使用哪一个取决于您需要的数据。例如,您是否需要索引,或者您只需要布尔值true
/ false
?
答案 3 :(得分:2)
如果你正在学习scala,我会好好看看Seq特征。它为scala的功能优点提供了基础。
答案 4 :(得分:1)
您也可以这样做,不需要知道Tuple2类中的字段名称 - 它使用模式匹配代替:
list find { case (x,y,_) => x == "C" && y == "D" }
当你知道你只需要一个时,“找到”是好的;如果你想找到所有匹配的元素,你可以使用“过滤器”或等效的含糖来理解:
for ( (x,y,z) <- list if x == "C" && y == "D") yield (x,y,z)
答案 5 :(得分:1)
这里的代码可以帮到你。
我有一个类似的情况,有一组基类条目(这里是A
),我想找到某个派生类的节点,如果有的话(这里是B
)。
class A
case class B(val name: String) extends A
object TestX extends App {
val states: List[A] = List( B("aa"), new A, B("ccc") )
def findByName( name: String ): Option[B] = {
states.find{
case x: B if x.name == name => return Some(x)
case _ => false
}
None
}
println( findByName("ccc") ) // "Some(B(ccc))"
}
此处(我的应用)的重要部分是findByName
不会返回Option[A]
,而是Option[B]
。
您可以轻松修改行为以返回B
,并在未找到任何内容时抛出异常。希望这会有所帮助。
答案 6 :(得分:1)
考虑collectFirst
为第一个匹配的元组提供Some[(String,String)]
,否则为None
,例如,如下所示,
xs collectFirst { case t@(a,_) if a == "existing" => t }
Some((existing,str))
scala> xs collectFirst { case t@(a,_) if a == "nonExisting" => t }
None
使用@
我们将元组的值绑定到t
,以便可以收集整个匹配的元组。