0

I have the following 2 lists:

val a = List(List(1,2,3),List(2,3,4),List(3,4,5))
val b = List(1,2,3)

I want to filter elements in a that contain an element in b and add them to a Map like so:

Map(1 -> List(List(1, 2, 3)), 2 -> List(List(1, 2, 3), List(2, 3, 4)), 3 -> List(List(1, 2, 3), List(2, 3, 4), List(3, 4, 5)))

I tried the following:

b.map(x => Map( x -> a.filter(y => y contains x)))

but it gives me

List(Map(1 -> List(List(1, 2, 3))), Map(2 -> List(List(1, 2, 3), List(2, 3, 4))), Map(3 -> List(List(1, 2, 3), List(2, 3, 4), List(3, 4, 5))))

How do I flatten this into a single Map? Is my approach wrong?

4

2 回答 2

3

首先,答案:

Map(b.map(i => (i, a.filter(_.contains(i)))):_*)

如您所见,您非常接近,但您打电话Map()(即,Map.apply())太“早”了。相反,您应该首先创建一个元组列表,因为您可以将一个元组序列传递给Map.apply().

更新:正如 aztek 所说,这可以简化:

b.map(i => (i, a.filter(_.contains(i)))).toMap
于 2012-12-22T21:11:11.353 回答
1

或者,如果parens让你眼花缭乱,

scala> for (k <- b; c <- a; if c contains k) yield k -> c
res4: List[(Int, List[Int])] = List((1,List(1, 2, 3)), (2,List(1, 2, 3)), (2,List(2, 3, 4)), (3,List(1, 2, 3)), (3,List(2, 3, 4)), (3,List(3, 4, 5)))

scala> .groupBy(_._1)
res5: scala.collection.immutable.Map[Int,List[(Int, List[Int])]] = Map(2 -> List((2,List(1, 2, 3)), (2,List(2, 3, 4))), 1 -> List((1,List(1, 2, 3))), 3 -> List((3,List(1, 2, 3)), (3,List(2, 3, 4)), (3,List(3, 4, 5))))

scala> .mapValues(_.map(_._2))
res6: scala.collection.immutable.Map[Int,List[List[Int]]] = Map(2 -> List(List(1, 2, 3), List(2, 3, 4)), 1 -> List(List(1, 2, 3)), 3 -> List(List(1, 2, 3), List(2, 3, 4), List(3, 4, 5)))

最近有人说他经常要做这个操作,就是扁平化值;现在我想知道这是否是他的意思。

于 2012-12-22T23:19:15.743 回答