Say I have two lists:
List(("a",1),("b",4),("d",5),("a",7),("b",6))
and
List("a","b","c","d")
and I want to group them based on the first list such that I get:
List("a" -> List(("a",1),("a",7)), "b" -> List(("b",4),("b",6)), "d" -> List(("d",5)))
What would be the best way to achieve this? I know I can use groupBy and pattern match against pre-determined values but when the second list is not pre-determined I get a little stuck.
Edit:
I need a copy of the object in the second list as the key for the processed list. I might need to group by a parameter of an on object in the second list but still maintain the entire object as the key... if that makes sense.
List(("a",1),("b",4),("d",5),("a",7),("b",6))
List(("a",1,1),("b",2,3),("c",5,6),("d",6,7))
becomes:
List(("a",1,1) -> List(("a",1),("a",7)), ("b",2,3) -> List(("b",4),("b",6)), ("d",6,7) -> List(("d",5)))
Sorry for lack of clarity!
Per your edit, with a for
-comprehension:
for {
key <- second
pair <- first.groupBy(_._1).get(key)
} yield key -> pair
Or the unsugared equivalent:
second.flatMap(key => first.groupBy(_._1).get(key).map(key -> _))
Both of these perform the groupBy
operation for every key. If this is an issue you can of course avoid it with the slightly more verbose:
val mappings = first.groupBy(_._1)
second.flatMap(key => mappings.get(key).map(key -> _))
And to address your new edit: if you need to transform each item in the second list to use it as a key for the first, there are a couple of ways you can go about that. For example, given:
val first = List(("a", 1), ("b", 4), ("d", 5), ("a", 7), ("b", 6))
val second = List(("a", 1, 1), ("b", 2, 3), ("c", 5, 6), ("d", 6, 7))
Either:
for {
item @ (key, _, _) <- second
pair <- first.groupBy(_._1).get(key)
} yield item -> pair
Or:
for {
item <- second
pair <- first.groupBy(_._1).get(item._1)
} yield item -> pair
Works as desired.
The solution is surprisingly simple:
first groupBy(_._1) toList
Result:
List((a,List((a,1), (a,7))), (d,List((d,5))), (b,List((b,4), (b,6))))
Where first
is your first list (what is the purpose of the second one)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With