Scala Collection 过滤多个项目

Scala Collection filtering on multiple items

我有以下递归函数来从列表 (zooResidents: List[(String, Int)]) 中删除另一个列表 (pets:列表[String])。它有效,但速度很慢。 Scala 的实现方式是什么?

val pets = List("cat", "dog")

val zooResidents = List(("cat", 4), ("lion", 2), ("tiger", 3), ("dog", 2) 

def removePets(zooResidents: List[(String, Int)], pets: List[String]): List[(String, Int)] =  {
  if (pets.isEmpty) zooResidents
  else removePets(zooResidents.filterNot(_._1.contains(pets.head)), pets.tail)
}

removePets(zooResidents, pets)      //> res2: List[(String, Int)] = List((lion,2), (tiger,3))

这就是我所说的 scala 方式

@ zooResidents filterNot { case (resident, _) => pets contains resident } 
res6: List[(String, Int)] = List(("lion", 2), ("tiger", 3))

为了获得更好的性能,pets 应该是 Set

filterNot 仅采用那些不满足谓词的元素,即那些给定函数 returns false 的元素。所以我们想要获取所有 pets 不包含元组第一个元素的元素。

你可以像我这样做的那样使用模式匹配而不是常规函数来解构元组

{ case (resident, _) => pets contains resident } 

这相当于

(residentTuple => pets.contains(residentTuple._1))

请注意 List#contains 是线性的,因为它必须扫描整个列表,我建议您使用具有恒定时间查找的数据结构,例如 Set

val petSet = pets.toSet
val filter = zooResidents.filterNot(element => petSet.contains(element._1))
val zooResidents = List(("cat", 4), ("lion", 2), ("tiger", 3), ("dog", 2)
val pets = List("cat", "dog")

试试这个单行:

zooResidents.filter(x=>pets.toSet.contains(x._1)==false)

scala> zooResidents.filter(x=>pets.toSet.contains(x._1)==false)
res167: List[(String, Int)] = List((lion,2), (tiger,3))

宠物更改为表演套装。

这需要 zooResidents 列表并检查 pets 中每个字符串的存在,returns 只有那些不在 pets 中的 zooResidents 元素 ==false 才会这样做。