【问题标题】:Returning an element from a List in Scala从 Scala 中的 List 返回一个元素
【发布时间】:2010-09-08 09:57:39
【问题描述】:

我最近在 Scala 中处理一个初学者项目,并且有一个关于 Scala 列表的初学者问题。

假设我有一个元组列表(例如List[Tuple2[String, String]])。是否有一种方便的方法可以从 List 中返回指定元组的第一次出现,还是需要手动遍历列表?

【问题讨论】:

    标签: scala list


    【解决方案1】:
    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))

    【讨论】:

    • 是否可以不返回 Some((C,D,1)) 而是返回 (C,D,1)?如果我使用 list(1),我的意思是一样的。
    • @grass 如果在列表中找不到三元组(C,D,1),返回值应该是什么?
    • 无或异常或空集。如果找不到三元组时有一种方法可以自定义返回值,那就太好了(除了编写我自己的 find() 方法)。
    • 'None' 和 'Some' 总是一起出现。他们制作了一个“选项[T]”。如果你的函数只是简单地返回'T',你必须通过异常来表示不存在这种情况。我会尽快添加一个答案,我认为它可以提供您想要的(使用“查找”)。
    【解决方案2】:

    您可以尝试使用find。 (更新了 find 的 scala-doc 位置)

    【讨论】:

      【解决方案3】:

      正如之前的评论中提到的,find 可能是最简单的方法。 Scala 的集合中实际上存在三种不同的“线性搜索”方法,每种方法返回的值略有不同。您使用哪一个取决于您需要数据的目的。例如,您需要一个索引,还是只需要一个布尔值true/false

      【讨论】:

      • 您能否提供有关这些“线性搜索”方法的更多信息?我正在寻找元组的索引(只有元组的一部分)
      • 其实我找到了我要找的东西:.zipWithIndex.collect { case ("partOfTuple", _, i) => i }
      【解决方案4】:

      如果您正在学习 scala,我会好好看看 Seq 特征。它为 scala 的大部分功能提供了基础。

      【讨论】:

        【解决方案5】:

        你也可以这样做,它不需要知道 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,即它将返回匹配属性的 所有 元素,而不是问题作者想要的唯一第一个。
        【解决方案6】:

        这里的代码可以帮助你。

        我有一个类似的情况,有一个基类条目集合(这里,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,如果没有找到则抛出异常。希望这会有所帮助。

        【讨论】:

          【解决方案7】:

          考虑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,这样就可以收集到整个匹配的元组。

          【讨论】:

            猜你喜欢
            • 2020-07-19
            • 2014-01-28
            • 1970-01-01
            • 2015-04-29
            • 1970-01-01
            • 2017-07-22
            • 2017-03-15
            • 1970-01-01
            • 2018-11-30
            相关资源
            最近更新 更多