scala - scala MatchError 从模式匹配创建元组
问题描述
我写了以下代码:
case class Filters(city: List[String], isType: List[String])
val input = "BNG:school | HYD:school,restaurant"
val(filter1:Filters, filter2:Filters) = input.split("\\|") match {
case Array(f1, f2) => (f1.split(":") match {
case Array(c,t) => t match {
case _ if t contains "," => Filters(List(c.trim), t.split(",").map(_.trim).toList)
case _ => Filters(List(c.trim), List(t.trim))
}
},
f2.split(":") match {
case Array(c,t) => t match {
case _ if t contains "," => Filters(List(c.trim), t.split(",").map(_.trim).toList)
case _ => Filters(List(c.trim), List(t.trim))
}
})
case _ => (input.split(":") match {
case Array(x,y) => Filters(List(x.trim), List(y.trim))
},Nil)
}
它提供以下输出:
filter1: Filters = Filters(List(BNG),List(school))
filter2: Filters = Filters(List(HYD),List(school, restaurant))
但是,如果我将输入更改为:val input = "BNG:school"
输出给出错误:
Exception in thread "main" scala.MatchError: (Filters(List(BNG),List(school)),List()) (of class scala.Tuple2)
我不知道我做错了什么?我有三种类型的输入:
BNG:school
HYD:school,restaurant
BNG:school | HYD:school,restaurant
该代码应该适用于这些类型的输入。
其次: 如果我从 filter1 和 filter2 中删除数据类型过滤器,则输出为:
filter1: Filters = Filters(List(BNG),List(school))
filter2: Product with Serializable = Filters(List(HYD),List(school, restaurant))
为什么filter1属于Filters类型,而filter2属于Product with Serializable类型?
任何帮助表示赞赏。
提前致谢。
解决方案
您的代码假定input
包含 2 个Filter
字符串。如果它实际上包含少于 2 个或多于 2 个,那么事情就会崩溃。
这可以通过多次、多种方式拆分输入来完成。
val input = "BNG:school | HYD:school,restaurant|LND,HKG:restaurant"
input.split("\\s*\\|\\s*")
.map { ss =>
val Array(cs, ts) = ss.split("\\s*:\\s*")
Filters(cs.split(",").toList, ts.split(",").toList)
}.toList
//res0 = List(Filters(List(BNG),List(school))
// , Filters(List(HYD),List(school, restaurant))
// , Filters(List(LND, HKG),List(restaurant)))
或者您可以使用正则表达式模式来帮助隔离数据元素。
val re = "([^|:]+):([^|:]+)".r
re.findAllMatchIn(input)
.map(m => Filters(m.group(1).trim.split(",").toList
,m.group(2).trim.split(",").toList)).toList
这里的一大优势是正则表达式搜索将简单地跳过格式错误的数据(例如丢失:
)而不是抛出错误。
正则表达式模式解释:
[^|:]
- 任何不是(^
意味着不是)横杠|
或冒号的字符:
[^|:]+
- 必须至少是其中的 1 个(+
表示1 个或多个)([^|:]+)
- 记住那个组(parens 创建一个“捕获组”)([^|:]+):([^|:]+)
- 2 个捕获组 (group(1)
andgroup(2)
) 以冒号分隔:
。每个组由冒号之前和之后的所有字符组成,这些字符不是竖线字符或冒号字符。