[英]In scala, how can I use pattern match to match a list with specified length?
My codes looks like this: 我的代码如下所示:
1::2::Nil match {
case 1::ts::Nil => "Starts with 1. More than one element"
case 1::Nil => "Starts with 1. Only one element"
}
I tried to use 1::ts::Nil
to match the List who starts with 1
and whose length is greater than 1. It workes well for 2-element list, however, this pattern doesn't work for 3-element list
, for example: 我尝试使用
1::ts::Nil
来匹配以1
开头且长度大于1
的List。它适用于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"
}
This won't work..Does anyone have ideas about this? 这不会有用。有人对此有想法吗?
You don't have to match on Nil. 你不必在Nil上匹配。 What you could do instead is match on the rest.
你可以做的是与其他人匹配。
1::Nil match {
case 1::ts::rest => "Starts with 1. More than one element"
case 1::Nil => "Starts with 1. Only one element"
}
With this code rest is than either a List or Nil and you make sure that the element has more than 1 element with the match on ts and then rest 使用此代码,其余部分不是List或Nil,并且您确保该元素具有多个元素,并且匹配ts然后休息
By rearranging the cases and adding a third case for completeness (exhaustive matching), this captures the intended semantics, 通过重新排列案例并添加第三个案例来完成(穷举匹配),这可以捕获预期的语义,
1 :: 2 :: 3 :: Nil match {
case 1 :: Nil => "Just one"
case 1 :: xs => "One and more"
case _ => "Unknown"
}
Note the second case extracts the first element and the rest which cannot be an empty list ( Nil
) since this possibility did not match in the first case: here, xs
includes at least one more non empty list; 注意第二种情况提取第一个元素,其余不能是空列表(
Nil
),因为这种可能性在第一种情况下不匹配:这里, xs
包括至少一个非空列表; the last case covers empty lists. 最后一个案例包括空列表。
In addition to the other answers, you can also use the apply method of the companion List object like so: 除了其他答案,您还可以使用伴随List对象的apply方法,如下所示:
1::2::3::Nil match {
case List(1, _, _*) => "Starts with 1. More than one element"
case List(1) => "Starts with 1. Only one element"
}
To generalize this problem, you might write your own extractor. 要概括这个问题,您可以编写自己的提取器。 To match on lists of an arbitrary length with a given first element, you could:
要匹配具有给定第一个元素的任意长度的列表,您可以:
object HeadWithLength {
def unapply[A](list: Seq[A]): Option[(Option[A], Int)] =
Some(list.headOption -> list.length)
}
And then you can match: 然后你可以匹配:
List(1, 3, 4) match {
case HeadWithLength(Some(head), length) => println(s"Head is $head and length is $length")
}
ts
is matching one element of the list. ts
匹配列表中的一个元素。 In your first case, ts
matches 2 ie 1
in the list matches with 1
in the pattern statement, ts
matches with 2
in the list and Nil
in the list matches with Nil
in the pattern statement and you don't get any MatchError 在你第一种情况下,
ts
匹配2即1
在列表中匹配1
的模式声明, ts
用火柴2
在列表中, Nil
在列表中匹配Nil
的模式声明,你没有得到任何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
In your second case, you are trying to match ts with both 2 and 3 which is not possible and hence it throws a MatchError. 在第二种情况下,您试图将ts与2和3匹配,这是不可能的,因此它会抛出MatchError。
If you want to do a pattern match based on size, you can do 如果你想根据大小进行模式匹配,你可以这样做
1 :: 2 :: 3 :: Nil match {
case 1 :: tail if tail.size > 1 => "Starts with 1. More than one element"
case 1 :: Nil => "Starts with 1. Only one element"
} //> res0: String = Starts with 1. More than one element
If case in the pattern match can be any condition for your real use case 如果模式匹配中的情况可以是您的实际用例的任何条件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.