2015-06-29 113 views
0

我正在Scala中使用帶有Spark版本的Scala。如何將scala的輸出格式從JSON格式化爲文本文件格式

斯卡拉 - 2.10.4 星火 - 1.2.0

我提下面我的情況。

我有一個RDD(說 - JoinOp)與元組嵌套(具有case類),例如 -

(123,(null,employeeDetails(Smith,NY,DW))) 
(456,(null,employeeDetails(John,IN,CS))) 

正在從具有兩個文件加入創建此RDD。

現在,我的要求是這個JSON格式的文本文件格式轉換沒有任何「空」和任何情況下,類名(這裏「employeeDetails」)。

我的期望的輸出是=

123,Smith,NY,DW 
456,John,IN,CS 

我與字符串插值試圖爲相同的,但與部分成功。

val textOp = JoinOp.map{jm => s"${jm._1},${jm._2._2}"} 

如果我打印textOp那麼它會給我下面的輸出。

123,employeeDetails(Smith,NY,DW) 
456,employeeDetails(John,IN,CS) 

現在,如果我嘗試訪問嵌套的元素與字符串插值「employeeDetails」案例類,它會拋出錯誤,如下面。

JoinOp.map{jm => s"${jm._1},${jm._2._2._1}"}.foreach(println) 

<console> :23: Error : value _1 is not member of jm 

在這裏,我可以理解,用上面的語法,它無法訪問「employeeDetails」案例類的嵌套元素。

什麼可能是這個問題的解決方案。任何幫助或點前進將有很大的幫助。

非常感謝, Pralay

回答

1

案例類有字段名。所以,而不是._1您需要使用該位置的字段名稱。假設如下定義:

case class EmployeeDetails(name: String, state: String) 

你訪問它

JoinOp.map{jm => s"${jm._1},${jm._2._2.name}"}.foreach(println) 
+0

謝謝@lulian。有效。有沒有什麼辦法可以引用「employeeDetails」案例類的所有字段,而不必明確提及它們的名稱。任何特殊字符會獲取所有字段嗎? –

+0

你可以使用'productElement(n:Int):Any'來檢索case類的每個元素,但是你會失去所有類型的信息(它返回Any)。通常人們更喜歡使用名稱,因爲代碼更清晰。 –

+0

謝謝呂蓮。我有另一種情況,我的RDD如下所示。 (123,(NULL,employeeDetails(credentails(XYZ,PASS),evaluationReport(80,100)))) 在這裏,如果我用下面的語法,我無法與訪問下面的代碼 joinOp 「XYZ」 的價值。地圖(op => s「$ {op._2._2._1}」)。 這裏最後的._1在最後無法從credentails case class中獲取值。什麼可能是嵌套case類值不可訪問的問題。 –

0

你可以這樣說:

case class EmployeeDetails(var0: String, var1: String, var2: String) 
val data = List((123,(null, EmployeeDetails("Smith", "NY", "DW")))) 

data.map {case (num, (sth, EmployeeDetails(var0, var1, var2))) => 
    s"$num,$var0,$var1,$var2"} 
1

如果你只需要打印案例類的各個領域,你可以使用productIterator遍歷字段列表。

val textOp = JoinOp.map { jm => 
    s"""${jm._1},${jm._2._2.productIterator.mkString(",")}""" 
}