简体   繁体   中英

How to find out common tuples from list of tuples using scala?

I have two list as following-

val list1 = List(("192.168.0.1","A"),("192.168.0.2","B"),("192.168.0.3","C"))
val list2 = List(("192.168.0.104",2), ("192.168.0.119",2), ("205.251.0.185",24), ("192.168.0.1",153))

I want to match first value of both lists as shown as following:

outputList = List(("192.168.0.1","A",153))

Currently I am using following to get output -

list1.map{
          ajson =>
            val findHost = list2.filter(_._1.contains(ajson._1.trim))
            if(findHost.nonEmpty) {
              (ajson._1,ajson._2,findHost.head._2)
            } else ("NA","NA",0)
        }.filterNot(p => p._1.equals("NA") || p._2.equals("NA"))

Is this right approach?

I also tried

(list1 ::: list2).groupBy(_._1).map{.......}

But it gives all elements from list1.

Can anyone help me to get expected output?

You can try this:

val res = for(
  (k,v) <- list1;
  n <- list2.toMap.get(k)
) yield (k,v,n)

Probably most performant would be

val m1 = list1.toMap
val m2 = list2.toMap

m1.keySet.intersect(m2.keySet).map(key => (key, m1(key), m2(key)))

UPDATE

If you have more complex shapes than Tuple2 in you list for example

val list1 = List(("192.168.0.1", "A", true, 'C'), ("192.168.0.2", "B", false, 'D'), ("192.168.0.3", "C", true, 'E'))
val list2 = List(("192.168.0.104", 2, 5.7), ("192.168.0.119", 2, 13.4), ("205.251.0.185", 24, 11.2), ("192.168.0.1", 153, 34.8))

, you may need additional reshaping like

val m1 = list1.view.map { case (key, v1, v2, v3) => (key, (v1, v2, v3)) }.toMap
val m2 = list2.view.map { case (key, v1, v2) => (key, (v1, v2)) }.toMap

m1.keySet.intersect(m2.keySet).map(key => (key, m1(key), m2(key)))

Or you could use enhanced johny's version with such reshaping :

val m2 = list2.view.map { case (key, v1, v2) => (key, (v1, v2)) }.toMap

list1.collect { case (ip, x1, x2, x3) if m2 contains ip => (ip, (x1, x2, x3), m2(ip)) }

The following code should do the trick

val result = list2.flatMap {
  entry =>
    map.get(entry._1.trim) match {
      case Some(list) =>
        Some(list.map {
          l =>
            (l._1, l._2, entry._2)
        })
      case None => None
    }
}.flatten
val list2Map = list2.toMap

list1.withFilter(x => list2Map.contains(x._1)).map(s => (s._1, s._2, list2Map(s._1)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM