Scala 匹配带有守卫的元组列表
Scala matching List of tuples with guards
我是 Scala 新手。作为练习,我正在尝试在带有守卫的元组列表上编写匹配语句。我知道地图可以解决问题,但我正在尝试了解模式匹配。
我试图编写一个以 List[(Char, Int)]
作为参数的函数。该函数对条目进行排序,如果两个条目具有相同的键值,则将它们相加。所以下面的参数 List(('q', 1'), ('a', 1), ('c', 2), ('a', 2), ('c', 1))
会变成 List(('a', 3), ('c', 3'), ('q', 1))
。
我有以下代码:
def sortAndAggregateList(chars: List[(Char, Int)]) : List[(Char, Int)] = {
chars match {
case (charP1, numP1) :: (charP2, numP2) :: (x : List[(String, Int)]) if (charP1 > charP2) =>
sortAndAggregateList((charP2, numP2) :: (charP1, numP1) :: x)
case (charP1, numP1) :: (charP2, numP2) :: (x : List[(String, Int)]) if (charP1 < charP2) =>
sortAndAggregateList((charP1, numP1) :: (charP2, numP2) :: x)
case (charP1, numP1) :: (charP2, numP2) :: (x : List[(String, Int)]) if (charP1 == charP2) =>
sortAndAggregateList((charP1, numP1 + numP2) :: x)
case Nil =>
Nil
}
}
但我收到以下警告:
:14: 警告:无结果类型测试:List[(Char, Int)] 类型的值不能同时是 List[(String, Int)](List[(String, Int)] 的基础) )(但仍可能匹配其擦除)
我尝试删除列表,但如果我这样做,我会收到 x
类型 Any
的错误。
有什么建议吗?
x 之后的额外类型注释不是必需的,也是错误的。
删除此
(x : List[(String, Int)])
改为使用(非强制。你可以省略类型注释)
(x : List[(Char, Int)])
功能齐全
def sortAndAggregateList(chars: List[(Char, Int)]): List[(Char, Int)] = chars match {
case (charP1, numP1) :: (charP2, numP2) :: x if charP1 > charP2 =>
sortAndAggregateList((charP2, numP2) :: (charP1, numP1) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if charP1 < charP2 =>
sortAndAggregateList((charP1, numP1) :: (charP2, numP2) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if charP1 == charP2 =>
sortAndAggregateList((charP1, numP1 + numP2) :: x)
case x => x
}
如果您考虑折叠元组,代码会更清晰
def sortAndAggregateList(chars: List[(Char, Int)]): List[(Char, Int)] = chars match {
case a :: b :: x if a._1 > b._2 =>
sortAndAggregateList(b :: a :: x)
case a :: b :: x if a._1 < b._1 =>
sortAndAggregateList(a :: b :: x)
case a :: b :: x if a._1 == b._1 =>
sortAndAggregateList((a._1, (a._2 + b._2)) :: x)
case x => x
}
大小写 case x => x
将匹配列表 Nil 大小写和具有一个元素大小写的列表。
错误是您在每个 case 语句之后进行的类型检查 (: List[(String, Int)])。
如果您将代码更改为以下错误消失:
def sortAndAggregateList(chars: List[(Char, Int)]) : List[(Char, Int)] = {
chars match {
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 > charP2) =>
sortList(p1 :: p2 :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 < charP2) =>
sortList(p2 :: p1 :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 == charP2) =>
val p3: (Char, Int) = (charP1, numP1 + numP2)
sortList(p3 :: x)
case x =>
x
case Nil =>
Nil
}
}
之后你会发现编译器告诉你p1和p2是未定义的。要解决此问题,您需要将它们设置为 p1 = (charP1, numP1) 和 p2 = (charP2, numP2)。
要使用您的语法解决此问题,您可以执行以下操作:
def sortAndAggregateList(chars: List[(Char, Int)]) : List[(Char, Int)] = {
chars match {
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 > charP2) =>
sortList((charP1, numP1) :: (charP2, numP2) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 < charP2) =>
sortList((charP2, numP2) :: (charP1, numP1) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 == charP2) =>
val p3: (Char, Int) = (charP1, numP1 + numP2)
sortList(p3 :: x)
case x =>
x
case Nil =>
Nil
}
}
现在唯一缺少的 link 是您尚未添加的 sortList 函数。
我不确定这是否可行,因为我认为是这样的:
case x => x
应该是:
case x :: Nil => x :: Nil
否则 x 将匹配任何内容。这也让您有可能删除案例:
case Nil => Nil
如果您不想删除大小写 x => x
我是 Scala 新手。作为练习,我正在尝试在带有守卫的元组列表上编写匹配语句。我知道地图可以解决问题,但我正在尝试了解模式匹配。
我试图编写一个以 List[(Char, Int)]
作为参数的函数。该函数对条目进行排序,如果两个条目具有相同的键值,则将它们相加。所以下面的参数 List(('q', 1'), ('a', 1), ('c', 2), ('a', 2), ('c', 1))
会变成 List(('a', 3), ('c', 3'), ('q', 1))
。
我有以下代码:
def sortAndAggregateList(chars: List[(Char, Int)]) : List[(Char, Int)] = {
chars match {
case (charP1, numP1) :: (charP2, numP2) :: (x : List[(String, Int)]) if (charP1 > charP2) =>
sortAndAggregateList((charP2, numP2) :: (charP1, numP1) :: x)
case (charP1, numP1) :: (charP2, numP2) :: (x : List[(String, Int)]) if (charP1 < charP2) =>
sortAndAggregateList((charP1, numP1) :: (charP2, numP2) :: x)
case (charP1, numP1) :: (charP2, numP2) :: (x : List[(String, Int)]) if (charP1 == charP2) =>
sortAndAggregateList((charP1, numP1 + numP2) :: x)
case Nil =>
Nil
}
}
但我收到以下警告:
:14: 警告:无结果类型测试:List[(Char, Int)] 类型的值不能同时是 List[(String, Int)](List[(String, Int)] 的基础) )(但仍可能匹配其擦除)
我尝试删除列表,但如果我这样做,我会收到 x
类型 Any
的错误。
有什么建议吗?
x 之后的额外类型注释不是必需的,也是错误的。
删除此
(x : List[(String, Int)])
改为使用(非强制。你可以省略类型注释)
(x : List[(Char, Int)])
功能齐全
def sortAndAggregateList(chars: List[(Char, Int)]): List[(Char, Int)] = chars match {
case (charP1, numP1) :: (charP2, numP2) :: x if charP1 > charP2 =>
sortAndAggregateList((charP2, numP2) :: (charP1, numP1) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if charP1 < charP2 =>
sortAndAggregateList((charP1, numP1) :: (charP2, numP2) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if charP1 == charP2 =>
sortAndAggregateList((charP1, numP1 + numP2) :: x)
case x => x
}
如果您考虑折叠元组,代码会更清晰
def sortAndAggregateList(chars: List[(Char, Int)]): List[(Char, Int)] = chars match {
case a :: b :: x if a._1 > b._2 =>
sortAndAggregateList(b :: a :: x)
case a :: b :: x if a._1 < b._1 =>
sortAndAggregateList(a :: b :: x)
case a :: b :: x if a._1 == b._1 =>
sortAndAggregateList((a._1, (a._2 + b._2)) :: x)
case x => x
}
大小写 case x => x
将匹配列表 Nil 大小写和具有一个元素大小写的列表。
错误是您在每个 case 语句之后进行的类型检查 (: List[(String, Int)])。
如果您将代码更改为以下错误消失:
def sortAndAggregateList(chars: List[(Char, Int)]) : List[(Char, Int)] = {
chars match {
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 > charP2) =>
sortList(p1 :: p2 :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 < charP2) =>
sortList(p2 :: p1 :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 == charP2) =>
val p3: (Char, Int) = (charP1, numP1 + numP2)
sortList(p3 :: x)
case x =>
x
case Nil =>
Nil
}
}
之后你会发现编译器告诉你p1和p2是未定义的。要解决此问题,您需要将它们设置为 p1 = (charP1, numP1) 和 p2 = (charP2, numP2)。 要使用您的语法解决此问题,您可以执行以下操作:
def sortAndAggregateList(chars: List[(Char, Int)]) : List[(Char, Int)] = {
chars match {
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 > charP2) =>
sortList((charP1, numP1) :: (charP2, numP2) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 < charP2) =>
sortList((charP2, numP2) :: (charP1, numP1) :: x)
case (charP1, numP1) :: (charP2, numP2) :: x if (charP1 == charP2) =>
val p3: (Char, Int) = (charP1, numP1 + numP2)
sortList(p3 :: x)
case x =>
x
case Nil =>
Nil
}
}
现在唯一缺少的 link 是您尚未添加的 sortList 函数。 我不确定这是否可行,因为我认为是这样的:
case x => x
应该是:
case x :: Nil => x :: Nil
否则 x 将匹配任何内容。这也让您有可能删除案例:
case Nil => Nil
如果您不想删除大小写 x => x