Scala 在每次迭代时在映射中获取修改的列表

Scala 在每次迭代时在映射中获取修改的列表,scala,Scala,语言是Scala 假设我有一个带有一些移动指令的位置(x,y)列表,我想用函数方法管理它们之间的冲突,我该怎么做 例如: 点a=[x=1,y=1]带有移动到[x=2,y=1]的指令 点b=[x=2,y=2]带有移动到[x=2,y=1]的指令 您的列表是[a,b],然后您希望应用该函数来移动它们并处理冲突。所以在上面的例子中,你应该注意到b和a之间的碰撞(b试图到达a的位置)。代码是什么 我现在得到的是: list.map(position => position.instruction.m

语言是Scala 假设我有一个带有一些移动指令的
位置(x,y)
列表,我想用函数方法管理它们之间的冲突,我该怎么做

例如:

点a=[x=1,y=1]
带有移动到
[x=2,y=1]的指令

点b=[x=2,y=2]
带有移动到
[x=2,y=1]的指令

您的列表是
[a,b]
,然后您希望应用该函数来移动它们并处理冲突。所以在上面的例子中,你应该注意到b和a之间的碰撞(b试图到达a的位置)。代码是什么

我现在得到的是:

list.map(position => position.instruction.move())
但它不处理碰撞。 我想做一些像

list.map(position => position.instruction.move()(list))
但该列表仅在地图末尾更新,因此b不会与a发生碰撞。事实上,碰撞正在用初始值进行验证。它使用的是一个位置[x=1,y=1],而不是新的位置[x=2,y=1]


使用for循环以迭代的方式很容易做到这一点,但是如何以函数的方式做到这一点呢?

一个选项是使用递归函数检查到目前为止修改过的点,并尝试检测碰撞,类似这样的

def moveCollisionAware(l: List[Position]) = {
  @scala.annotation.tailrec
  def move(l: List[Position], acc: List[Position]): Either[String, List[Position]] = l match {
     case Nil => Right(acc)
     case head :: tail =>
       val newPosition = head.move(2, 1)
       if (acc.contains(newPosition))
         Left(s"Moving $head will clash with an existent position")
       else
         move(tail, acc :+ newPosition)
  }

  move(l, List.empty)
}
这基本上就是您所需要的(也是了解发生了什么的一个好方法),一旦您对列表API更熟悉,您就可以使用
foldLeft
并实现同样的效果

差不多

positions.foldLeft(Right(List.empty[Position]): Either[String, List[Position]]) {
  case (Right(acc), position) =>
    val newPosition = position.move(2, 1)
    if (acc.contains(newPosition))
      Left(s"Moving $position will clash with an existent position")
    else
      Right(acc :+ newPosition)
    case (e @ Left(_), _) => e
}

这个问题可以改进。请参阅和上的“帮助”部分以获取灵感。到目前为止,您尝试了什么?list.map(position=>position.instruction.move()(list)),我只是尝试了这个方法,然后遇到了问题。我不知道该怎么办万一发生碰撞,你会怎么做?你需要使用reduce或fold来代替map-然后你可以在到达hanks时创建更新的列表!你太棒了!我已经知道了褶皱,但这是一个非常好的技巧!:)@1)不要评估用户,而是评估问题和答案的质量。2)如果你发现这个答案至少和布鲁诺一样令人吃惊,那么就考虑一下它的投票吧。1)这个用户给了我答案,我认为他的答案是他头脑的一部分。还是一样,不要对新客户感到不安。我不能推翻他的回答。