带有守卫的元组匹配列表



我是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

有什么建议吗?

错误是您在每个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
  }
}

现在唯一缺少的链接是您没有添加的sortList函数。我不确定这是否会起作用,因为我认为这种情况:

case x => x
应:

case x :: Nil => x :: Nil

否则x将匹配任何值。这也给你留下了去掉盒子的可能性:

case Nil => Nil

如果你不想删除大小写x => x

x后面的额外类型注释是不必要的,也是错误的。

remove this

(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 case x => x将匹配list Nil case和list只有一个元素case。

相关内容

  • 没有找到相关文章

最新更新