Reputation: 158
I am getting following List[JSONObject] structure as a output of some snippet-
List(List({
"groupName": "group1",
"maxSeverity": -1,
"hostCount": 3,
"members": [
"192.168.20.11",
"192.168.20.52",
"192.168.20.53"
]
}),
List(),
List({
"groupName": "group1",
"maxSeverity": -1,
"hostCount": 2,
"members": [
"192.168.20.20",
"192.168.20.52"
]
}))
I want to merge whole output to form a list which contains - 1) group name
2) severity - which will be minimum from all list elements
3) hostcout - addition of hostcount from all list elements
4) members - similar array without duplicate values from all list elements.
So output will be somewhat like this-
List({
"groupName": "group1",
"maxSeverity": -1,
"hostCount": 5,
"members": [
"192.168.20.11",
"192.168.20.52",
"192.168.20.53",
"192.168.20.20",
"192.168.20.52"
]
})
How do I merge whole list to a single list to get above mentioned output???
Upvotes: 0
Views: 428
Reputation: 2205
Consider using Jackson to parse these into a case class, and then work with the data that way.
object JsonMerge {
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
case class ServerGroup(groupName: String, hostCount: Int, maxSeverity: Int, members: Iterable[String])
def collapseGroup(groups: List[ServerGroup]): ServerGroup = {
val members = groups.flatMap(_.members).toSet
ServerGroup(groups.head.groupName, members.size, groups.map(_.maxSeverity).min, members)
}
def main(args: Array[String]) {
val objectMapper = new ObjectMapper with ScalaObjectMapper
objectMapper.registerModule(DefaultScalaModule)
val allGroups = objectMapper.readValue[List[ServerGroup]](rawData)
val output = allGroups.groupBy(_.groupName).values.map(collapseGroup)
objectMapper.writerWithDefaultPrettyPrinter().writeValue(System.out, output)
}
val rawData = """
[{
"groupName": "group1",
"hostCount": 3,
"maxSeverity": -1,
"members": [
"192.168.20.11",
"192.168.20.52",
"192.168.20.53"
]
},{
"groupName": "group1",
"hostCount": 2,
"maxSeverity": -1,
"members": [
"192.168.20.20",
"192.168.20.52"
]
},{
"groupName": "group2",
"hostCount": 1,
"maxSeverity": 2,
"members": [
"192.168.20.52"
]
}]"""
}
This has this output:
[ {
"groupName" : "group2",
"hostCount" : 1,
"maxSeverity" : 2,
"members" : [ "192.168.20.52" ]
}, {
"groupName" : "group1",
"hostCount" : 4,
"maxSeverity" : -1,
"members" : [ "192.168.20.11", "192.168.20.52", "192.168.20.53", "192.168.20.20" ]
} ]
Upvotes: 1
Reputation: 8487
This is what you may need:
object JsonMerge {
def main(args: Array[String]) {
val l1 = List(List(
JSON.parseFull(
"""
{
"groupName": "group1",
"maxSeverity": -1,
"hostCount": 3,
"members": [
"192.168.20.11",
"192.168.20.52",
"192.168.20.53"
]
}
""").get.asInstanceOf[Map[String, Any]]),
List(),
List(
JSON.parseFull("""
{
"groupName": "group1",
"maxSeverity": -1,
"hostCount": 2,
"members": [
"192.168.20.20",
"192.168.20.52"
]
}
""").get.asInstanceOf[Map[String, Any]]),
List(
JSON.parseFull("""
{
"groupName": "group2",
"maxSeverity": 2,
"hostCount": 1,
"members": [
"192.168.20.52"
]
}
""").get.asInstanceOf[Map[String, Any]])).flatten
// println(l1)
// println(l1.groupBy(_("groupName")))
val minimumSeverity = -1
val mergedList = l1.groupBy(_("groupName")).map { grouped =>
val folded = grouped._2.foldLeft(Map[String, Any]("maxSeverity" -> minimumSeverity)) { (current, next) =>
val severity1 = current.get("maxSeverity").map(s => s match {
case v: Int => v
case _ => minimumSeverity
}).getOrElse(minimumSeverity)
val severity2 = current.get("maxSeverity").map(s => s match {
case v: Int => v
case _ => minimumSeverity
}).getOrElse(minimumSeverity)
val severity = Math.max(severity1, severity2)
val m1 = current.get("members").map(n => n match {
case l: List[_] => l
case _ => List()
}).getOrElse(List()).toSet
val m2 = next.get("members").map(n => n match {
case l: List[_] => l
case _ => List()
}).getOrElse(List()).toSet
val members = m1 union m2
Map("maxSeverity" -> severity,
"hostCount" -> members.size,
"members" -> members.toList)
}
folded + ("groupName" -> grouped._1)
}
mergedList foreach println
}
}
Map(maxSeverity -> -1, hostCount -> 1, members -> List(192.168.20.52), groupName -> group2)
Map(maxSeverity -> -1, hostCount -> 4, members -> List(192.168.20.11, 192.168.20.52, 192.168.20.53, 192.168.20.20), groupName -> group1)
Upvotes: 0