【问题标题】:Pattern match element of list in ScalaScala中列表的模式匹配元素
【发布时间】:2015-05-30 03:39:57
【问题描述】:

我正在尝试这样做:

def contains(x: Int, l: List[Int]) = l match { // this is just l.contains(x)
  case _ :: x :: _ => true
  case _ => false
}

不幸的是它不起作用

scala> contains(0, List(1, 2, 3))
res21: Boolean = true

scala> contains(1, List(1, 2, 3))
res22: Boolean = true

scala> contains(3, List(1, 2, 3))
res23: Boolean = true

你能解释一下为什么吗?

【问题讨论】:

    标签: list scala pattern-matching


    【解决方案1】:

    要匹配等于x 的数字,您可以将其放入反引号中:

    def contains(x: Int, l: List[Int]) = l match {
      case _ :: `x` :: _ => true
      case _ => false
    }
    

    不幸的是,:: 匹配器只从列表中获取一个项目——第一个,所以这段代码只能在l 中找到第二个项目:

    scala> contains(1, List(1,2,3))
    res2: Boolean = false
    
    scala> contains(2, List(1,2,3))
    res3: Boolean = true
    
    scala> contains(3, List(1,2,3))
    res4: Boolean = false
    

    我相信,如果没有递归,您无法匹配列表中的任意项目:

    def contains(x: Int, l: List[Int]): Boolean = l match { // this is just l.contains(x)
      case `x` :: xs => true
      case _ :: xs => contains(x, xs)
      case _ => false
    }
    

    【讨论】:

    • 感谢您提醒我有关 反引号。很遗憾:: 只取了一项:(
    【解决方案2】:

    第一种情况匹配非空列表中的任何项目,注意,

    scala> contains(123, List(1, 2, 3))
    res1: Boolean = true
    
    scala> contains(123, List())
    res2: Boolean = false
    

    匹配列表头项的递归方法可能有效。

    【讨论】:

    • 谢谢。不幸的是我不想递归。
    【解决方案3】:

    首先,case 部分中的x 是局部变量的别名。你传递给方法的不是x

    其次,_ :: x :: _ 匹配任何包含两个或更多元素的列表。所以你所有的输出都是true

    【讨论】:

      【解决方案4】:

      这可能有效,

        def contains(y: Int, l: List[Int]) = l match { // this is just l.contains(x)
          case _ :: x :: _  if(x == y)=> true
          case _ => false
        }
      

      【讨论】:

      • 太棒了!谢谢。我可以以某种方式摆脱这个if(x == y) 吗?
      • @Michael,为什么你不想要那个保护条件?
      • 只是为了美观
      【解决方案5】:

      您的方法不起作用,因为模式匹配中的x 绑定到第二个列表元素具有的任何值。它基本上是一个新鲜的变量。

      替代 S.K 的答案

      def contains(y: Int, l: List[Int]) = l match { // this is just l.contains(x)
        case _ :: x :: _  => x == y
        case _ => false
      }
      

      或者你也可以写

      def contains[A](y: A, l: Seq[Int]) = (l.lift)(1).exists(_ == y)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-14
        • 2017-10-14
        • 1970-01-01
        • 2015-07-29
        • 2014-08-27
        相关资源
        最近更新 更多