1

这就是我现在正在做的事情:

  private var accounts = Vector.empty[Account]

  def removeAccount(account: Account)
  {
    accounts = accounts.filterNot(_ == account)
  }

有没有更易读的解决方案?理想情况下,我想写accounts = accounts.remove(account).

4

5 回答 5

5

不幸的是没有,更糟糕的是(也许),如果同一个帐户出现两次,filterNot将删除它们。我唯一能提供的可读性就是使用

accounts.filter(_ != account)

另一种可能性是使用具有删除操作的集合类型,例如 a TreeSet(它被称为-)。如果您无论如何都没有重复的条目,那么 aSet完全可以。(当然,对于某些操作来说它比较慢,但它可能更适合应用程序——它在删除单个条目时更有效;filterNot你基本上必须重新构建整个条目Vector。)

于 2013-03-12T14:47:47.147 回答
5

我会用这个:

accounts filterNot account.==

这对我来说读起来很好,但是ymmv。我也想要一个count不带谓词的,但是集合库确实缺乏专门的方法,其中一个带有谓词的方法可以概括操作。

在 2.8.x 之前,由于语义问题,有一种方法 iirc 被弃用了-如果我的记忆对我有用,它实际上可能会在 2.10 恢复,但事实并非如此。编辑:我检查了它,发现它-现在保留给一个可变方法,该方法修改它所应用的集合。我完全赞成-:/:-尽管在序列上,在其中删除第一个或最后一个元素等于某物是有意义的。有人愿意为此买票吗?我会赞成。:-)

于 2013-03-12T16:25:01.387 回答
5

你可以这样做:

def removeFirst[T](xs: Vector[T], x: T) = {
  val i = xs.indexOf(x)
  if (i == -1) xs else xs.patch(i, Nil, 1)
}

然后

accounts = removeFirst(accounts, account)

不过,我认为问题的关键在于 aVector可能不是您想要取出的一Set项目的正确集合类型(提示:try )。如果您想对 ID 或插入索引进行索引,那么Map可能就是您所追求的(它确实有一个-方法)。如果你想有效地索引多个事物,你需要一个数据库!

于 2013-03-12T17:06:09.980 回答
4

您可以使用diff为所有序列定义的方法。它计算两个序列之间的多重集差异 - 这意味着它将根据需要删除尽可能多的元素。

Vector(1, 2, 1, 3, 2).diff(Seq(1)) => 
Vector(2, 1, 3, 2)

Vector(1, 2, 1, 3, 2).diff(Seq(1, 1)) =>
Vector(2, 3, 2)

Vector(1, 2, 1, 3, 2).diff(Seq(1, 1, 2))  
Vector(3, 2)
于 2013-03-12T15:28:01.853 回答
0

如果你不想使用filterNot闭包,你可以使用更详细但更明确的理解风格。

private var accounts = Vector.empty[Account]

def removeAccount(account: Account)
{
    accounts = for { a <- accounts
                     if a != account } yield { a }
}

在这种情况下是否感觉更好,这是个人喜好问题。

当然,对于涉及嵌套 flatMaps 等的更复杂的表达式,我同意 Martin Odersky 的建议,即 for-comprehensions 可以更容易阅读,尤其是对于新手而言。

于 2013-03-15T15:16:23.833 回答