Scala 合并地图列表
Scala merge list of maps
输入=
val data = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2))),
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
预期输出:
val data = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2),
Map("id" -> "hindi", "status" -> 1),
Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
我试图在不删除旧键的情况下将“子”键值合并到列表中,但我无法获取它。任何人都可以使用 scala 帮助解决这个问题。
首先创建一些案例 类。使用这些比使用地图更容易。
case class Person(id: String, name: String, sub: List[Language])
case class Language(id: String, status: Int)
现在,创建 Person
的列表:
val data = List(
Person("123", "raju", List(Language("english", 2))),
Person("123", "raju", List(Language("english", 0), Language("hindi", 0))))
我不知道您的合并逻辑是什么,但假设您只想连接具有相同 ID 的人的 sub
-列表。你可以这样做:
// Gets a map from ID to the list of persons with that ID
data.groupBy(_.id)
// Gets a List[List[Person]] (the values of the map)
.values
// Makes a new Person out of the inner list of persons, concatenating all the languages of that person.
.map(persons => Person(
persons.head.id,
persons.head.name,
persons.flatMap(_.sub)))
这里是一个像你的例子一样在纯 Maps/Lists 上工作的例子。
val data = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2))),
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
val expected = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2),
Map("id" -> "hindi", "status" -> 1),
Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
val res = data.groupBy(x => (x.get("id"), x.get("name"))).collect { case (_, items) =>
items.reduceLeft { (l, r) =>
l.updated("sub", l("sub").asInstanceOf[List[_]] ++ r("sub").asInstanceOf[List[_]])
}
}
println(res)
https://scalafiddle.io/sf/FBj4Mvi/0
PS:老实说,创建类型化结构(正如其他人所建议的那样)可能仍然是更好的解决方案。
输入=
val data = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2))),
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
预期输出:
val data = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2),
Map("id" -> "hindi", "status" -> 1),
Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
我试图在不删除旧键的情况下将“子”键值合并到列表中,但我无法获取它。任何人都可以使用 scala 帮助解决这个问题。
首先创建一些案例 类。使用这些比使用地图更容易。
case class Person(id: String, name: String, sub: List[Language])
case class Language(id: String, status: Int)
现在,创建 Person
的列表:
val data = List(
Person("123", "raju", List(Language("english", 2))),
Person("123", "raju", List(Language("english", 0), Language("hindi", 0))))
我不知道您的合并逻辑是什么,但假设您只想连接具有相同 ID 的人的 sub
-列表。你可以这样做:
// Gets a map from ID to the list of persons with that ID
data.groupBy(_.id)
// Gets a List[List[Person]] (the values of the map)
.values
// Makes a new Person out of the inner list of persons, concatenating all the languages of that person.
.map(persons => Person(
persons.head.id,
persons.head.name,
persons.flatMap(_.sub)))
这里是一个像你的例子一样在纯 Maps/Lists 上工作的例子。
val data = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2))),
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
val expected = List(
Map("id" -> "123", "name" -> "raju",
"sub" -> List(Map("id" -> "english", "status" -> 2),
Map("id" -> "hindi", "status" -> 1),
Map("id" -> "english", "status" -> 0),
Map("id" -> "hindi", "status" -> 0))))
val res = data.groupBy(x => (x.get("id"), x.get("name"))).collect { case (_, items) =>
items.reduceLeft { (l, r) =>
l.updated("sub", l("sub").asInstanceOf[List[_]] ++ r("sub").asInstanceOf[List[_]])
}
}
println(res)
https://scalafiddle.io/sf/FBj4Mvi/0
PS:老实说,创建类型化结构(正如其他人所建议的那样)可能仍然是更好的解决方案。