如何将没有重复的元素折叠到单个案例类实例中?

时间:2014-12-23 20:06:27

标签: scala

让我们说,有一个案例类User

case class User(id: Int, name: String, habits: Seq[Habit])

和另一个案例类Habit

case class Habit(id: Int, name: String)

habits seq:

val habits = Seq(
  User(1, "user name", Seq(Habit(1, "habit name 1"))),
  User(1, "user name", Seq(Habit(2, "habit name 2"))),
  User(1, "user name", Seq(Habit(1, "habit name 1")))
)

我想将列表添加到每个用户ID的User个案例类的单个实例中,例如: 1,在删除重复的习惯后,例如上面Habit(1, "habit name 1")

基本上输出应如下:

User(1, "user name", Seq(Habit(1, "habit name 1"), Habit(2, "habit name 2"))

将所有习惯合并在一个用户之下,没有重复。

保证User个对象具有相同的user idname

3 个答案:

答案 0 :(得分:2)

以这种方式使用groupBy将为您提供Map[(Int, String), List[User]],假设(id, name)对是唯一的,则允许您折叠属于每个密钥的用户列表。

list.groupBy(user => (user.id, user.name))
    .map { case ((id, name), duplicates) =>
        User(id, name, duplicates.flatMap(_.habits).distinct)
    }.toList

请注意,对于包含多个用户的列表,groupBy将无法维护其订单。

答案 1 :(得分:2)

由于保证所有习惯属于同一用户,您可以

  1. FlatMap用户列出一个习惯列表,然后拨打distinct
  2. 复制任何用户(可能是head),将习惯更改为新的合并列表
  3. habits.head.copy(habits=habits.flatMap(_.habits).distinct)

答案 2 :(得分:1)

可能这就是你想要的:

val users = List(
  User(1, "user name", List(Habit(1, "habit name 1"))),
  User(1, "user name", List(Habit(2, "habit name 2"))),
  User(1, "user name", List(Habit(1, "habit name 1"))))

val result = users.foldLeft(users.head)((r, u) => 
  r.copy(habits = (r.habits ++ u.habits).distinct))
println(result)
// User(1,user name,List(Habit(1,habit name 1), Habit(2,habit name 2)))