Scala具有保护的元组匹配列表

Scala具有保护的元组匹配列表,scala,pattern-matching,pattern-guards,Scala,Pattern Matching,Pattern Guards,我是斯卡拉的新手。作为一个练习,我试图在一个带卫士的元组列表上写一个匹配语句。我知道一张地图可以解决这个问题,但我正试图了解模式匹配 我试图编写一个函数,将列表[(Char,Int)]作为参数。该函数对条目进行排序,如果两个条目具有相同的键值,则将它们相加。所以下面的参数List(('q',1'),('a',1),('c',2),('a',2),('c',1))将变成List(('a',3),('c',3'),('q',1)) 我附带以下代码: def sortAndAggregateList(

我是斯卡拉的新手。作为一个练习,我试图在一个带卫士的元组列表上写一个匹配语句。我知道一张地图可以解决这个问题,但我正试图了解模式匹配

我试图编写一个函数,将
列表[(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
  }
}
def sortAndAggregateList(chars:List[(Char,Int)]):List[(Char,Int)]={
字符匹配{
大小写(charP1,numP1)::(charP2,numP2)::(x:List[(String,Int)])如果(charP1>charP2)=>
sortAndAggregateList((charP2,numP2):(charP1,numP1)::x)
大小写(charP1,numP1)::(charP2,numP2)::(x:List[(String,Int)])如果(charP1
sortAndAggregateList((charP1,numP1):(charP2,numP2)::x)
大小写(charP1,numP1)::(charP2,numP2)::(x:List[(String,Int)])如果(charP1==charP2)=>
sortAndAggregateList((charP1,numP1+numP2)::x)
案例无=>
无
}
}
但我得到以下警告:

:14:警告:无结果类型测试:List[(Char,Int)]类型的值也不能是List[(String,Int)](List[(String,Int)]的底层)(但仍可能与其擦除匹配)

我试图删除列表,但如果我这样做,我会得到一个错误,即
x
属于
Any
类型


有什么建议吗?

没有必要在x之后添加额外的类型注释,而且是错误的

去掉这个

(x : List[(String, 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)]=字符匹配{
大小写(charP1,numP1)::(charP2,numP2)::如果charP1>charP2=>
sortAndAggregateList((charP2,numP2):(charP1,numP1)::x)
大小写(charP1,numP1)::(charP2,numP2)::如果charP1
sortAndAggregateList((charP1,numP1):(charP2,numP2)::x)
大小写(charP1,numP1)::(charP2,numP2)::如果charP1==charP2=>
sortAndAggregateList((charP1,numP1+numP2)::x)
案例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

  }
def sortAndAggregateList(chars:List[(Char,Int)]):List[(Char,Int)]=字符匹配{
案例a::b::x如果a._1>b._2=>
sortAndAggregateList(b::a::x)
如果a._1
sortAndAggregateList(a::b::x)
案例a::b::x如果a.。\u 1==b.\u 1=>
sortAndAggregateList((a._1,(a._2+b._2))::x)
案例x=>x
}

case
case x=>x
将同时匹配list Nil case和具有一个元素case的list。

错误是在每个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
  }
}
应该是:

case x :: Nil => x :: Nil
否则x会匹配任何东西。这也让您有可能移除该案例:

case x => x
case Nil => Nil

如果您不想删除案例x=>x

请查看错误消息:您正在与
chars
进行匹配,后者是一个
列表[(Char,Int)]
,但在模式中,您希望
x
是一个
列表[(String,Int)]
。是的,您是对的,这就是我添加它匹配任何内容的原因,即使是Nil.case Nil=>Nil也是冗余的。此函数有一个缺点。它不适用于只包含一个条目的列表,如:list((“t”,1))
case x :: Nil => x :: Nil
case Nil => Nil