如何模式匹配字符串中的第一个字符

时间:2018-05-31 20:21:24

标签: scala recursion pattern-matching

我只是学习scala,并将代码的出现作为练习。我知道模式匹配在Haskell中很流行,并且希望在scala中做类似的事情。

def part1(visited: Set[Coord], current: Coord, directions: String):  Set[Coord] = directions match {
  case "^" :: tail => part1(visited + current, current.up, tail)
  case "v" :: tail => part1(visited + current, current.down, tail)
  case "<" :: tail => part1(visited + current, current.left, tail)
  case ">" :: tail => part1(visited + current, current.right, tail)
  case _ => visited + current // The string is empty
}

我尝试使用数组或字符列表而不是字符串进行转换,但一直卡住。我上面粘贴的代码报告:

Day3.scala:8: error: constructor cannot be instantiated to expected type;
 found   : scala.collection.immutable.::[B]
 required: Array[Char]
    case '^' :: tail => part1(visited + current, current.up, tail)
             ^

2 个答案:

答案 0 :(得分:2)

migrate,也称为Cons,是::的构造函数,具有头部和尾部。您有List表示String,因此除非明确转换为Array[Char],否则不能使用List语义。你能做的就是使用警卫:

List[Char]

注意def part1(visited: Set[Coord], current: Coord, directions: String): Set[Coord] = directions match { case x if x.startsWith("^") => part1(visited + current, current.up, x.tail) case x if x.startsWith("v") => part1(visited + current, current.down, x.tail) case x if x.startsWith("<") => part1(visited + current, current.left, x.tail) case x if x.startsWith(">") => part1(visited + current, current.right, x.tail) case _ => visited + current // The string is empty } 来自tail,而不是直接来自IndexedSeqOptimized

答案 1 :(得分:1)

::仅针对列表定义,而String可以隐式转换为Seq,但结果不是List - 您可以使用{ {1}}将toList转换为Seq。另外,使用单引号创建List而不是字符串:

Char

或者,您可以仅匹配directions.toList match { case '^' :: tail => // ... case 'v' :: tail => // ... case '<' :: tail => // ... case '>' :: tail => // ... case _ => // ... } 的结果(仅返回第一个字符或headOption):

None