从scala中的List [[Object,Exception]]中筛选出重复项

时间:2014-03-17 16:33:42

标签: scala

我正在使用的列表可能包含userInfo对象或 一个例外。我现在要做的是过滤掉所有重复的userInfo 对象。应在userInfo中的电子邮件属性上进行过滤。 完成后我想返回List列表[[InvitePatternException,UserInfo]]

val filtered = list.map {
  case Success(userInfo) => Right(userInfo)
  case Failure(ex: InvitePatternException) => Left(ex)
}

所以我的问题是,我应该如何以及何时进行过滤?我应该过滤 列表[[InvitePatternException,UserInfo]]或之前? scala的做法是什么?

2 个答案:

答案 0 :(得分:1)

这一次超过了两个列表: 1.过滤掉异常 2.用于删除基于属性的重复项。

Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_65).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class UserInfo(name: String, age: Int, email: String)
defined class UserInfo

scala> case class InvitePatternException(e: String) extends Throwable(e)
defined class InvitePatternException

scala> val eitherList: List[Either[InvitePatternException, UserInfo]] = 
List(
  Right(UserInfo("a",1,"a.mail.com")), 
  Right(UserInfo("b",1,"b.mail.com")), 
  Right(UserInfo("c",1,"a.mail.com")), 
  Right(UserInfo("d",5,"d.mail.com")), 
  Left(InvitePatternException("failed for user with name = d")), 
  Left(InvitePatternException("failed for user with name = e")), 
  Right(UserInfo("e",7,"a.mail.com"))
)

eitherList: List[Either[InvitePatternException,UserInfo]] = List(Right(UserInfo(a,1,a.mail.com)), Right(UserInfo(b,1,b.mail.com)), Right(UserInfo(c,1,a.mail.com)), Right(UserInfo(d,5,d.mail.com)), Left(InvitePatternException: failed for user with name = d), Left(InvitePatternException: failed for user with name = e), Right(UserInfo(e,7,a.mail.com)))

scala> val resultList = eitherList.filter(_.isLeft) ::: eitherList.collect { case Right(userInfo) => userInfo }.groupBy(_.email).map(_._2.head).map(Right(_)).toList
resultList: List[Either[InvitePatternException,UserInfo]] = List(Left(InvitePatternException: failed for user with name = d), Left(InvitePatternException: failed for user with name = e), Right(UserInfo(d,5,d.mail.com)), Right(UserInfo(a,1,a.mail.com)), Right(UserInfo(b,1,b.mail.com)))

答案 1 :(得分:1)

我或多或少地采用与其他任何编程语言相同的方式:保留一组你已经看过的东西,并跳过一个项目,如果它在看到的集合中(结果类型在下面省略)减少噪音):

scala> val items = Seq(
     Right(1), 
     Right(2), 
     Left(new Exception), 
     Left(new Exception), 
     Right(1), 
     Right(3)
)
items = List(Right(1), Right(2), Left(java.lang.Exception), Left(java.lang.Exception), Right(1), Right(3))

scala> val uniques = { 
    var seen = Set[Int](); 
    items.collect { 
      case Left(x) => Left(x); 
      case Right(i) if !seen(i) => 
        seen += i
        Right(i) 
    }
}
uniques = List(Right(1), Right(2), Left(java.lang.Exception), Left(java.lang.Exception), Right(3))

不要忘记,尽管Scala程序员更喜欢不可变状态,但在使用(本地)可变状态时,没有任何内在的恶意,这是最干净的解决方案。