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
才会这样做。
我有以下递归函数来从列表 (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
才会这样做。