如何取消嵌套具有以下类型的spark rdd((String,scala.collection.immutable.Map [String,scala.collection.immutable.Map [String,Int]]))

时间:2015-06-16 15:59:58

标签: scala cassandra apache-spark

当我将其打印到屏幕

时,它是一个嵌套地图,内容如下
(5, Map ( "ABCD" -> Map("3200" -> 3,
                    "3350.800" -> 4, 
                    "200.300" -> 3)
 (1, Map ( "DEF" -> Map("1200" -> 32,
                        "1320.800" -> 4, 
                        "2100" -> 3)

我需要得到类似的东西

Case Class( 5, ABCD 3200, 3)
Case Class(5, ABCD 3350.800, 4)
CaseClass(5,ABCD., 200.300, 3)
CaseClass(1, DEF 1200, 32)
CaseClass(1 DEF, 1320.800, 4)
等等 基本上是一个案例类列表

并将其映射到案例类对象,以便我可以将其保存到cassandra。 我已经尝试过做flatMapValues但是un unsts只有一个级别。也用flatMap。那也不起作用或者我犯了错误

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

使用for-comprehension和一些模式匹配来解构事物相当简单:

 val in = List((5, Map ( "ABCD" -> Map("3200" -> 3,  "3350.800" -> 4, "200.300" -> 3))),
               (1, Map ("DEF" -> Map("1200" -> 32, "1320.800" -> 4, "2100" -> 3))))

case class Thing(a:Int, b:String, c:String, d:Int)

 for  { (index, m) <- in
        (k,v) <-m
        (innerK, innerV) <- v}
        yield Thing(index, k, innerK, innerV) 

//> res0: List[maps.maps2.Thing] = List(Thing(5,ABCD,3200,3), 
//                                      Thing(5,ABCD,3350.800,4),
//                                      Thing(5,ABCD,200.300,3), 
//                                      Thing(1,DEF,1200,32),
//                                      Thing(1,DEF,1320.800,4),
//                                      Thing(1,DEF,2100,3))

所以让我们挑选一下for-comprehension

(index, m) <- in

这与

相同
t <- in
(index, m) = t

在第一行t将连续设置为in的每个元素。 因此,t是一个元组(Int, Map(...)) Patten匹配让我们在右侧为元组添加“patten”,编译器选择元组,将index设置为Int,将m设置为Map。

(k,v) <-m

如前所述相当于

u <-m
(k, v) = u

这一次u获取了Map的每个元素。这又是关键和价值的元组。因此,k会连续设置为每个键,v设置为值。

v是你的内部地图,所以我们用内部地图再次做同样的事情

(innerK, innerV) <- v}

现在我们拥有了创建案例类所需的一切。 yield只是说每次循环都会收集“屈服”的东西。

yield Thing(index, k, innerK, innerV) 

在幕后,这只是转换为一组地图/平面图

yield只是值Thing(index, k, innerK, innerV)

我们为v

的每个元素获取其中一个
v.map{x=>val (innerK, innerV) = t;Thing(index, k, innerK, innerV)}

但是外部地图的每个元素都有一个内部地图

m.flatMap{y=>val (k, v) = y;v.map{x=>val (innerK, innerV) = t;Thing(index, k, innerK, innerV)}}

flatMap,因为如果我们刚刚执行map并且我们想要将其展平为仅列出项目列表,我们会得到一个列表列表。

同样,我们为List

中的每个元素执行其中一个
in.flatMap (z => val (index, m) = z; m.flatMap{y=>val (k, v) = y;v.map{x=>val (innerK, innerV) = t;Thing(index, k, innerK, innerV)}}

我们在_1_2 style-y。

中执行此操作
in.flatMap (z=> z._2.flatMap{y=>y._2.map{x=>;Thing(z._1, y._1, x._1, x._2)}}}

产生完全相同的结果。但作为理解不是更清楚吗?

答案 1 :(得分:1)

如果您更喜欢收集操作,可以这样做

ls