【问题标题】:Scala iterate over a map represented by a boardScala 遍历由棋盘表示的地图
【发布时间】:2016-03-31 01:42:55
【问题描述】:

我创建了一个函数来解析一个 81 个字符长的字符串。在解析它时,我需要使用一个名为neighbors(Int: row, Int: col) 的函数,它返回指定行和列的所有垂直、水平和对角线坐标。使用这个坐标列表,我需要从每个坐标列出的每个可能值中删除我放置的值。板表示为地图,我需要在功能上执行此操作,即不使用 var。

这是我的解析函数:

str.zipWithIndex.map{
    case (digit, index) => ((index / 9, index % 9), List(digit.asDigit))
  }.toMap

以下是我对neighbors 函数的了解:

def neighbors(row: Int, col: Int): List[(Int, Int)]

例如,如果解析器位于坐标(0,2),并且输入到地图中的数字是4,我将不得不从该点的所有垂直、水平和对角坐标中删除4 .每个点的值都表示为可能值的列表。

我也没有得到neighbor函数的实现。

感谢您的帮助!

【问题讨论】:

  • 1st - 我认为Karl's suggestion 对您的解析器来说是一个更好的设计。第二 - 很难建议如何使用 neighbor 函数而不看到它的确切签名,或者至少是它的返回数据类型。第三 - 您无法从尚未填充的坐标中删除任何内容,因此从您的描述看来,neighbor 必须在 parse 完成后对每个元素调用。
  • 我同意,Karl 的建议很棒。我想出了如何用列表填充空单元格。当我发布这个问题时,我还没有弄清楚。我会更新问题。另外,我将添加neighbor 函数的签名。谢谢!

标签: list scala dictionary


【解决方案1】:

如果我正确理解了您的问题,它是关于如何在保持功能的同时改变事物(在这种情况下从 Map 中删除)?

如果是,有两种方法:

  1. 创建每次迭代调用的尾递归函数,其中包含要处理的剩余元素列表和“可变”数据的当前状态:

    @tailrec
    def process(
         input: List[(Char, Int)],
         board: Map[Any, Any],
         resultAccum: List[Result]): List[Result] = input match {
      case Nil => resultAccum.reverse
      case (char, pos) :: tail =>
        // do the processing
        val updatedBoard = board - ??? // create update version of the board
        val updateResults = ??? :: resultAccum
        process(tail, updatedBoard, updateResults)
    }
    
  2. 或者你可以使用foldLeft,同样的,但看起来更短:

    input.foldLeft((initialBoard, List[Result]())) {
      case ((board, resultsAccum), (char, pos)) =>
        val updatedBoard = board - ??? // create update version of the board
        val updateResults = ??? :: resultsAccum
        (updatedBoard, updateResults)
    }._2.reverse
    

    foldLeft 的初始状态包含板的初始状态和空的结果列表。

【讨论】:

    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    相关资源
    最近更新 更多