如何将var转换为List?

时间:2018-03-14 09:29:43

标签: scala

如何将一个var转换为两个var列表?

以下是我的输入变量:

val input="[level:1,var1:name,var2:id][level:1,var1:name1,var2:id1][level:2,var1:add1,var2:city]"

我希望我的结果应该是:

  val first= List(List("name","name1"),List("add1"))
  val second= List(List("id","id1"),List("city"))

2 个答案:

答案 0 :(得分:3)

首先,input 不是有效的json

val input="[level:1,var1:name,var2:id][level:1,var1:name1,var2:id1][level:2,var1:add1,var2:city]"

你必须使它有效json RDD (因为你将使用apache spark)

val validJsonRdd = sc.parallelize(Seq(input)).flatMap(x => x.replace(",", "\",\"").replace(":", "\":\"").replace("[", "{\"").replace("]", "\"}").replace("}{", "}&{").split("&"))

一旦你有有效的json rdd,你可以轻松地将其转换为dataframe ,然后应用你拥有的逻辑

import org.apache.spark.sql.functions._
val df = spark.read.json(validJsonRdd)
  .groupBy("level")
  .agg(collect_list("var1").as("var1"), collect_list("var2").as("var2"))
  .select(collect_list("var1").as("var1"), collect_list("var2").as("var2"))

应该在dataframe 中获得所需的输出

+------------------------------------------------+--------------------------------------------+
|var1                                            |var2                                        |
+------------------------------------------------+--------------------------------------------+
|[WrappedArray(name1, name2), WrappedArray(add1)]|[WrappedArray(id1, id2), WrappedArray(city)]|
+------------------------------------------------+--------------------------------------------+

如果需要,您可以将数组转换为列表

要获得问题中的值,您可以执行以下操作

val rdd = df.collect().map(row => (row(0).asInstanceOf[Seq[Seq[String]]], row(1).asInstanceOf[Seq[Seq[String]]]))

val first = rdd(0)._1.map(x => x.toList).toList
//first: List[List[String]] = List(List(name1, name2), List(add1))

val second = rdd(0)._2.map(x => x.toList).toList
//second: List[List[String]] = List(List(id1, id2), List(city))

我希望答案很有帮助

答案 1 :(得分:2)

reduceByKey是实现所需输出的重要功能。关于step by step reduceByKey explanation

的更多解释

您可以执行以下操作

val input="[level:1,var1:name1,var2:id1][level:1,var1:name2,var2:id2][level:2,var1:add1,var2:city]"
val groupedrdd = sc.parallelize(Seq(input)).flatMap(_.split("]\\[").map(x => {
  val values = x.replace("[", "").replace("]", "").split(",").map(y => y.split(":")(1))
  (values(0), (List(values(1)), List(values(2))))
})).reduceByKey((x, y) => (x._1 ::: y._1, x._2 ::: y._2))


val first = groupedrdd.map(x => x._2._1).collect().toList
//first: List[List[String]] = List(List(add1), List(name1, name2))
val second = groupedrdd.map(x => x._2._2).collect().toList
//second: List[List[String]] = List(List(city), List(id1, id2))
相关问题