【发布时间】:2010-09-08 09:57:39
【问题描述】:
我最近在 Scala 中处理一个初学者项目,并且有一个关于 Scala 列表的初学者问题。
假设我有一个元组列表(例如List[Tuple2[String, String]])。是否有一种方便的方法可以从 List 中返回指定元组的第一次出现,还是需要手动遍历列表?
【问题讨论】:
我最近在 Scala 中处理一个初学者项目,并且有一个关于 Scala 列表的初学者问题。
假设我有一个元组列表(例如List[Tuple2[String, String]])。是否有一种方便的方法可以从 List 中返回指定元组的第一次出现,还是需要手动遍历列表?
【问题讨论】:
【讨论】:
(C,D,1),返回值应该是什么?
您可以尝试使用find。 (更新了 find 的 scala-doc 位置)
【讨论】:
正如之前的评论中提到的,find 可能是最简单的方法。 Scala 的集合中实际上存在三种不同的“线性搜索”方法,每种方法返回的值略有不同。您使用哪一个取决于您需要数据的目的。例如,您需要一个索引,还是只需要一个布尔值true/false?
【讨论】:
.zipWithIndex.collect { case ("partOfTuple", _, i) => i }
如果您正在学习 scala,我会好好看看 Seq 特征。它为 scala 的大部分功能提供了基础。
【讨论】:
你也可以这样做,它不需要知道 Tuple2 类中的字段名称——它使用模式匹配来代替:
list find { case (x,y,_) => x == "C" && y == "D" }
当你知道你只需要一个时,“find”很好;如果你想找到所有匹配的元素,你可以使用“过滤器”或等效的含糖来理解:
for ( (x,y,z) <- list if x == "C" && y == "D") yield (x,y,z)
【讨论】:
filter,即它将返回匹配属性的 所有 元素,而不是问题作者想要的唯一第一个。
这里的代码可以帮助你。
我有一个类似的情况,有一个基类条目集合(这里,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,这样就可以收集到整个匹配的元组。
【讨论】: