Combining two lists in Scala

后端 未结 8 769
北海茫月
北海茫月 2021-01-04 00:58

From 2 lists of the form List[(Int, String):

l1 = List((1,\"a\"),(3,\"b\"))
l2 = List((3,\"a\"),(4,\"c\"))

how can I combine t

相关标签:
8条回答
  • 2021-01-04 01:37

    Another opaque onetwo-liner of questionable efficiency yet indubitable efficacy:

    val lst = l1 ++ l2
    lst.map(_._2).distinct.map(i => (lst.filter(_._2 == i).map(_._1).sum, i))
    
    0 讨论(0)
  • 2021-01-04 01:39
    val l = l1 ::: l2
    val m = Map[String, Int]()
    (m /: l) {
      case (map, (i, s)) => { map.updated(s, i + (map.get(s) getOrElse 0))}
    }.toList // Note: Tuples are reversed.
    

    But I suppose there is a more elegant way to do the updated part.

    0 讨论(0)
  • 2021-01-04 01:39

    How about,

    (l1 ++ l2).groupBy(_._2).mapValues(_.unzip._1.sum).toList.map(_.swap)
    

    Unpacking this a little on the REPL helps to show what's going on,

    scala> l1 ++ l2
    res0: List[(Int, java.lang.String)] = List((1,a), (3,b), (3,a), (4,c))
    
    scala> res0.groupBy(_._2)
    res1: ... = Map(c -> List((4,c)), a -> List((1,a), (3,a)), b -> List((3,b)))
    
    scala> res1.mapValues(_.unzip)
    res2: ... = Map(c -> (List(4),List(c)), a -> (List(1, 3),List(a, a)), b -> (List(3),List(b)))                         
    
    scala> res1.mapValues(_.unzip._1)                                                                                                                                                                      
    res3: ... = Map(c -> List(4), a -> List(1, 3), b -> List(3))                                                                                    
    
    scala> res1.mapValues(_.unzip._1.sum)
    res4: ... = Map(c -> 4, a -> 4, b -> 3)                                                                                                               
    
    scala> res4.toList                                                                                                                                                                                     
    res5: List[(java.lang.String, Int)] = List((c,4), (a,4), (b,3))                                                                                                                                        
    
    scala> res5.map(_.swap)
    res6: List[(Int, java.lang.String)] = List((4,c), (4,a), (3,b))
    
    0 讨论(0)
  • 2021-01-04 01:44
    val a = List(1,1,1,0,0,2)
    val b = List(1,0,3,2)
    
    scala> List.concat(a,b)
    res31: List[Int] = List(1, 1, 1, 0, 0, 2, 1, 0, 3, 2)
    
    (or) 
    
    scala> a.:::(b)
    res32: List[Int] = List(1, 0, 3, 2, 1, 1, 1, 0, 0, 2)
    
    (or) 
    
    scala> a ::: b
    res28: List[Int] = List(1, 1, 1, 0, 0, 2, 1, 0, 3, 2)
    
    0 讨论(0)
  • 2021-01-04 01:55
    for ( (k,v) <- (l1++l2).groupBy(_._2).toList ) yield ( v.map(_._1).sum, k )
    
    0 讨论(0)
  • 2021-01-04 01:56

    Note that with this solution, the lists are traversed twice.

    val l3 = (l1 zip l2).foldRight(List[(Int, String)]()) {
      case ((firstPair @ (firstNumber, firstWord),
            secondPair @ (secondNumber, secondWord)),
            result) =>
        if (firstWord == secondWord)
          ((firstNumber + secondNumber), firstWord) :: result
        else
          firstPair :: secondPair :: result
    }
    
    0 讨论(0)
提交回复
热议问题