我最近一直在做一个 Scala 的初学者项目,并且有一个关于 Scala 列表的初学者问题。
假设我有一个元组列表(List[Tuple2[String, String]]
例如)。是否有一种方便的方法可以从列表中返回指定元组的第一次出现,或者是否需要手动遍历列表?
scala> val list = List(("A", "B", 1), ("C", "D", 1), ("E", "F", 1), ("C", "D ", 2), ("G", "H", 1)) 列表: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> 列表查找 {e => e._1 == "C" && e._2 == "D"} res0: 选项[(java.lang.String, java.lang.String, Int)] = Some((C,D,1))
您可以尝试使用find。(更新了查找的 scala-doc 位置)
正如之前的评论中提到的,find
这可能是最简单的方法。Scala 的集合中实际上存在三种不同的“线性搜索”方法,每种方法返回的值略有不同。您使用哪一个取决于您需要数据的目的。例如,您需要一个索引,还是只需要一个布尔值true
/ false
?
如果你正在学习 scala,我会好好看看Seq特征。它为 scala 的大部分功能提供了基础。
您也可以这样做,这不需要知道 Tuple2 类中的字段名称——它使用模式匹配来代替:
list find { case (x,y,_) => x == "C" && y == "D" }
当您知道您只需要一个时,“查找”很好;如果你想找到所有匹配的元素,你可以使用“过滤器”或等效的含糖来理解:
for ( (x,y,z) <- list if x == "C" && y == "D") yield (x,y,z)
这是可能对您有所帮助的代码。
我有一个类似的案例,有一组基类条目(这里,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
,如果没有找到则抛出异常。希望这可以帮助。
考虑为第一个匹配元组或其他方式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
以便可以收集整个匹配的元组。