Home > Software engineering >  In scala how to combine List of Map, of unequal size based on common keys with same value
In scala how to combine List of Map, of unequal size based on common keys with same value

Time:11-11

Input:

val list1 = List(
    Map("ID" -> "123", "NAME" -> "P1", "PID" -> "321"),
    Map("ID" -> "456", "NAME" -> "P2",  "PID" -> "333")
)

val list2 = List(
    Map("ID" -> "123", "ADDRESS" -> "A1")
)

val list3 = List(
    Map("PID" -> "321", "PHONE" -> "2222"), 
    Map("PID" -> "789", "PHONE" -> "4444")
)

Output:

List(
    Map(
        "ID" -> "123", 
        "NAME" -> "P1", 
        "PID" -> "321", 
        "ADDRESS" -> "A1", 
        "PHONE" -> "2222"
    )
)

I tried iterating list over flatmate and map, but it had bad time complexity. Expecting a solution in more functional programming approach, not using loop. Thanks in advance for helping with providing solution.

list1
  .flatMap { l1 =>
    list2
      .flatMap { l2 =>
        list3
          .map { l3 =>

            if ((l1.ID === l2.ID) && (l1.PID === l3.PID)) {

              val data = Map(
                "ID" -> l1.ID,
                "NAME" -> l1.NAME,
                "PID" -> l1.PID,
                "ADDRESS" -> l2.ADDRESS,
                "PHONE" -> l3.PHONE,
              )

              val temp = List(data)
              temp              
            }

          }
      }
  }

CodePudding user response:

I would first create two Maps, one for ID -> ADDRESS and one for PID -> PHONE from list2 and list3 respectively.

scala> val addressByID = list2.map(x => x("ID") -> x("ADDRESS")).toMap
val addressByID: Map[String, String] = Map(123 -> A1)

scala> val phoneByPID = list3.map(x => x("PID") -> x("PHONE")).toMap
val phoneByPID: Map[String, String] = Map(321 -> 2222, 789 -> 4444)

Then use for to assemble the data:

scala> for {
  x <- list1
  address <- addressByID.get(x("ID"))
  phone <- phoneByPID.get(x("PID"))
} yield x    Map("ADDRESS" -> address, "PHONE" -> phone)
val res1: List[Map[String, String]] = List(HashMap(NAME -> P1, PID -> 321, PHONE -> 2222, ADDRESS -> A1, ID -> 123))

CodePudding user response:

(list1    list2    list3).reverse.reduce(_    _)

This creates a single list of Maps and then reduces them to a single Map. The reverse is needed so that the earlier values take precedence.

  • Related