Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于列表元素索引的Scala映射列表_Scala_Apache Spark - Fatal编程技术网

基于列表元素索引的Scala映射列表

基于列表元素索引的Scala映射列表,scala,apache-spark,Scala,Apache Spark,我在Scala中创建了一个字符串列表,这些字符串表示表中的列名: val cols = List("Col1","Col2","Col3") 我想将其转换为以下字符串 (select Col1 as value,sum(1) as count from sometable group by Col1) a union (select Col2 as value,sum(1) as count from sometable group by Col2) union (select Col3 as

我在Scala中创建了一个字符串列表,这些字符串表示表中的列名:

val cols = List("Col1","Col2","Col3")
我想将其转换为以下字符串

(select Col1 as value,sum(1) as count from sometable group by Col1) a
union (select Col2 as value,sum(1) as count from sometable group by Col2)
union (select Col3 as value,sum(1) as count from sometable group by Col3)
其目的是通过Spark SQL执行此字符串,以创建一个新的dataframe,其中包含cols列表中列出的所有列的摘要。实际SQL代码不仅包含sum1组件,而且与问题无关

一般来说,我对Scala和编程都是全新的,我发现这很棘手,主要是因为在转换字符串的第一个并集之前,您选择了必需的a或任何别名

因此,我提出了以下解决方案:不要判断,有没有更好的方法

def mapWithIndex (s : String, i : Int) {

var outputString = ""
if (i == 0) {outputString="(Select "+s+" as value, sum(1) as freq from sometable group by "+s+") a"}
else {outputString="(Select "+s+" as value, sum(1) as freq from sometable group by "+s+")"}
return outputString
}

val transformedString = cols.zipWithIndex.map(case (s,i) => mapWithIndex(s,i)).mkString(" union ")
代码中可能有一些小错误,因为我必须重新键入我无法从正在工作的服务器上复制的所有内容,但我相信您已经了解了其中的要点。 虽然这样做很好,但我感觉自己效率低下,原因如下,可能还有很多:

看起来必须能够将所需的逻辑放入map语句中的匿名函数中。我找不到访问列表项索引的方法,该索引将显示是否应该在字符串中包含darn a。 mapWithIndex函数包含一个var,而不是一个val,从我所读到的内容来看,我应该尽量避免使用它 感觉mapWithIndex函数不应该在每个条件中重复整个select语句,而应该仅在i==0时追加a。我不能理解正确的语法。 非常感谢您阅读我的问题,并提前感谢您可能提供的任何帮助。

val selects=cols.mapc=>s选择$c作为值,按$c从sometable组中选择sum1作为计数
val transformedString = cols
  .zipWithIndex
  .map {
    case (name, index) => s"(select $name as value,sum(1) as count from sometable group by $name)" + (if (index==0) " a" else "")
  }
  .mkString(" union ")
val transformedString=selects.head+selects.tail.mkString联合,联合,
尼亚夫罗的答案看起来不错。我想指出的是,在scala中,if是一个表达式,因此它被计算并返回一个值,因此mapWithIndex函数应该完全跳过outputString变量,并使用if I==0的主体作为第一个字符串或第二个字符串。为了避免重复输入相同的内容,你可以按照nyavro的建议去做,他只是在匿名函数中完成了。谢谢Lukasz!像这样,前两个查询不使用union连接。