这就是我现在正在做的事情:
private var accounts = Vector.empty[Account]
def removeAccount(account: Account)
{
accounts = accounts.filterNot(_ == account)
}
是否有更易读的解决方案?理想情况下,我想写accounts = accounts.remove(account)
。
答案 0 :(得分:5)
遗憾的是,如果相同的帐户出现两次,则更糟糕的是(或许更糟),filterNot
将删除它们。我可以提供的唯一可读性是使用
accounts.filter(_ != account)
另一种可能性是使用具有删除操作的集合类型,例如TreeSet
(称为-
)。如果您还没有重复的条目,Set
完全没问题。 (当然,对于某些操作来说速度较慢,但它可能更适合应用程序 - 它更有效地删除单个条目;使用filterNot
您基本上必须构建整个Vector
试。)
答案 1 :(得分: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)
答案 2 :(得分:3)
我会用这个:
accounts filterNot account.==
这对我来说很好看,但是ymmv。我还想要一个不带谓词的count
,但是集合库真的缺乏专门的方法,其中一个带谓词的人可以概括操作。
直到2.8.x,是一个-
方法,由于语义问题而被弃用,iirc。如果我的记忆正确地为我服务,它实际上可能会回到2.10,但事实并非如此。 修改:我查了一下,看到-
现在为 mutable 方法保留,该方法修改了应用它的集合。我会全神贯注于-:
/ :-
虽然在序列上,将第一个或最后一个元素放到某个位置是有意义的。有人愿意为此买票吗?我赞成它。 : - )
答案 3 :(得分:3)
你可以这样做:
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)
我认为问题的结论是,Vector
可能不是 set 项目的正确集合类型,你想把它们拉出来(提示) :尝试Set
)。如果要索引ID或插入索引,那么Map
可能就是您所追求的(具有-
方法)。如果你想有效地索引多个事物,你需要一个数据库!
答案 4 :(得分:0)
如果您不想使用filterNot
闭包,则可以使用更详细但更明确的for-comprehension样式。
private var accounts = Vector.empty[Account]
def removeAccount(account: Account)
{
accounts = for { a <- accounts
if a != account } yield { a }
}
在这种情况下,是否感觉更好是个人偏好的问题。
当然对于涉及嵌套flatMaps等的更复杂的表达式,我同意Martin Odersky的建议,即for-comprehensions可以更容易阅读,特别是对于新手。