在scala中,如何使用模式匹配来匹配具有指定长度的列表?

时间:2015-02-21 10:48:45

标签: list scala functional-programming pattern-matching

我的代码如下:

1::2::Nil match {
  case 1::ts::Nil => "Starts with 1. More than one element"
  case 1::Nil => "Starts with 1. Only one element"
}

我尝试使用1::ts::Nil来匹配以1开头并且长度大于1的列表。它适用于2元素列表,但是,这种模式并不适用为3-element list工作,例如:

1::2::3::Nil match {
  case 1::ts::Nil => "Starts with 1. More than one element"
  case 1::Nil => "Starts with 1. Only one element"
}

这不会起作用。有人对此有什么想法吗?

5 个答案:

答案 0 :(得分:6)

你不需要在Nil上匹配。你可以做的是与其他人匹配。

1::Nil match {
   case 1::ts::rest => "Starts with 1. More than one element"
   case 1::Nil => "Starts with 1. Only one element"
}

使用此代码,可以使用List或Nil,并确保元素具有多个元素,并且匹配ts,然后休息

答案 1 :(得分:2)

通过重新排列案例并添加第三个案例以实现完整性(穷举匹配),这可以捕获预期的语义,

1 :: 2 :: 3 :: Nil match {
  case 1 :: Nil => "Just one"
  case 1 :: xs => "One and more"
  case _ => "Unknown"
}

注意第二种情况提取第一个元素,其余不能是空列表(Nil),因为这种可能性在第一种情况下不匹配:这里,xs至少包含一个非空列表;最后一个案例包括空名单。

答案 2 :(得分:2)

除了其他答案,您还可以使用伴侣List对象的apply方法,如下所示:

$(document).on('pageshow', '#page', function () { 
  /* do stuff */ 
}).on('click', '.openBulk', function() {
  $('.bulk').show();
})

$('.close').click(function() {
  $(this).closest('.bulk').hide();
})

答案 3 :(得分:1)

要概括此问题,您可以编写自己的提取程序。要匹配具有给定第一个元素的任意长度的列表,您可以:

object HeadWithLength {
    def unapply[A](list: Seq[A]): Option[(Option[A], Int)] = 
        Some(list.headOption -> list.length)
}

然后你可以匹配:

List(1, 3, 4) match {
    case HeadWithLength(Some(head), length) => println(s"Head is $head and length is $length") 
}

答案 4 :(得分:0)

ts匹配列表中的一个元素。在第一种情况下,ts匹配2,即列表中的1与模式语句中的1匹配,ts与列表中的2匹配,{列表中的{1}}与模式语句中的Nil匹配,并且您没有得到任何MatchError

Nil

在你的第二种情况下,你试图将ts与2和3匹配,这是不可能的,因此它会引发MatchError。

如果您想根据尺寸进行模式匹配,可以执行


1 :: 2 :: Nil match {
    case 1 :: ts :: Nil => println("ts is "+ts)
                         "Starts with 1. More than one element"
    case 1 :: Nil       => "Starts with 1. Only one element"
  } //> ts is 2
   //| res1: String = Starts with 1. More than one element

如果模式匹配中的情况可以是您的实际用例的任何条件