如何从Vector中删除元素?

时间:2013-03-12 14:39:20

标签: scala collections vector immutability trie

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

  private var accounts = Vector.empty[Account]

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

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

5 个答案:

答案 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可以更容易阅读,特别是对于新手。