I have the following list:
List(List(("hello", "goodbye", 12), ("hello", "goodbye", 15)), List(("hello", "test", 18), ("hello", "test", 20)), List(("something", "different", 30), ("something", "different", 18)))
I would like to get the following result:
List(("hello", "goodbye", 27), ("hello", "test", 38), ("something", "different", 48))
I've tried to use .map and .groupBy, but I can't seem to find a way to get it working.
CodePudding user response:
This appears to get what you're after as long as the order of result elements is unimportant.
val data =
List(List(("hello", "goodbye", 12), ("hello", "goodbye", 15)), List(("hello", "test", 18), ("hello", "test", 20)), List(("something", "different", 30), ("something", "different", 18)))
data.flatten
.groupMapReduce(tup => (tup._1,tup._2))(_._3)(_ _)
.map{case ((k1,k2),v) => (k1,k2,v)}
.toList
//res0: List[(String, String, Int)] =
// List((hello,test,38), (something,different,48), (hello,goodbye,27))
Notice that I flatten
away all the inner sub-Lists and focus only on the String
elements in the tuples. It's not completely clear if that's what you intend.
CodePudding user response:
You can:
- Flatten those lists into a single list
- Group by the first two elements of each list
- Reduce on the third element of each list in each group
val list = List(
List(("hello", "goodbye", 12), ("hello", "goodbye", 15)),
List(("hello", "test", 18), ("hello", "test", 20)),
List(("something", "different", 30), ("something", "different", 18))
)
val result = list.flatten.groupBy { case (s1, s2, _) => (s1, s2) }.values.map(_.reduce((s1, s2) => (s1._1, s1._2, s1._3 s2._3)))
// List((hello,test,38), (hello,goodbye,27), (something,different,48))
CodePudding user response:
If inner list can have different "keys" - you can flatten your list of lists with flatMap(identity)
or flatten
then group the result using first two elements of the tuples and reduce the groupping with sum:
val collection = ...
collection
.flatten
.groupMapReduce(t => (t._1, t._2))(identity)((l,r) => (l._1, l._2, l._3 r._3))
.values
.toList