Scala Collection过滤多个项目

时间:2016-06-01 16:50:15

标签: scala recursion functional-programming scala-collections tail-recursion

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

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
       bla bla do some sync simple stuffs etc...
       ...
       await Task.Run(() => Utility.MailUtility.SendEmail(user.Email, user.To, msg, subj));
       return RedirectToAction("Index", "Home");
    }

3 个答案:

答案 0 :(得分:4)

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

val petSet = pets.toSet
val filter = zooResidents.filterNot(element => petSet.contains(element._1))

答案 1 :(得分:2)

这就是我所说的scala方式

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

为了获得更好的效果,pets应为Set

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

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

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

这与

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

答案 2 :(得分: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列表,并检查宠物中每个字符串的存在,并仅返回==false中不存在于宠物中的zooResidents元素。