在Scala中使用for comprehension时修改列表

问题描述 投票:1回答:1

我有一个包含客户之间所有可能交易的清单,并且需要比较每个买卖组合。通过比较,需要修改另一个列表。

我有以下代码:

def res(input_orders: List[Order], input_clients: List[Client]): List[Client] = {
  for {
    order1 <- input_orders
    order2 <- input_orders if check_order(order1, order2)
    firstClient = input_clients.find(_.name == order1.client)
    secondClient = input_clients.find(_.name == order2.client)
    tmp <- if (order1.operation == 's') {    
      input_clients.map { case `firstClient` => sell(firstClient.get, order1); case x => x }
      input_clients.map { case `secondClient` => buy(secondClient.get, order2); case x => x }
    } else {
      input_clients.map { case `firstClient` => buy(firstClient.get, order1); case x => x }
      input_clients.map { case `secondClient` => sell(secondClient.get, order2); case x => x }
    }
  } yield tmp
}

但它按原样返回客户端列​​表,不会对其进行修改。

我想问题出在这个“修改”块中:

  input_clients.map { case `firstClient` => sell(firstClient.get, order1); case x => x }
  input_clients.map { case `secondClient` => buy(secondClient.get, order2); case x => x }
} else {
  input_clients.map { case `firstClient` => buy(firstClient.get, order1); case x => x }
  input_clients.map { case `secondClient` => sell(secondClient.get, order2); case x => x }

这有什么问题?

scala pattern-matching
1个回答
0
投票

回想一下,map函数是不可变的,这意味着它不会对数据结构进行任何修改,而是返回一个内容已更新的新对象。

在你提到的块中,mapare的第一次调用没用,因为从不使用返回值。实现您最初想要完成的任务的正确方法是:

val order = order1.operation == 's'
input_clients.map {
  case `firstClient` => if (order) sell(firstClient.get, order1) else buy(firstClient.get, order1)
  case `secondClient` => if (order) buy(secondClient.get, order2) else sell(secondClient.get, order2)
  case x => x
}

此外,避免使用getOption[T]访问器(想象如果选项是None会发生什么)。更喜欢更安全的操作,如模式匹配或flatMap / for-comprehension。

© www.soinside.com 2019 - 2024. All rights reserved.