繁体   English   中英

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

[英]Scala map list based on list element index

我在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执行此字符串以创建一个新的数据框,其中包含cols列表中列出的所有列的摘要(实际的SQL代码不仅包含sum(1)组件,而且与问题无关) 。

我对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 ")

代码中可能存在一些小错误,因为我不得不重新输入所有内容(我无法复制我正在工作的服务器),但我确信你会得到它的要点。 虽然这很好但感觉我因为以下原因而效率低下(可能还有很多):

  1. 看起来必须可以将所需的逻辑放入map()语句中的匿名(?)函数中。 我找不到一种方法来访问List项索引,该索引将显示字符串中是否应包含“a”。
  2. mapWithIndex函数包含一个var而不是val,从我读过的内容我应该尽量避免
  3. 感觉mapWithIndex函数不应该在每个条件中重复整个select语句,而只是如果i == 0则只附加“a”。我无法正确获得语法。

非常感谢您阅读我的问题,并提前感谢您提供的任何帮助。

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 selects = cols.map(c => s"(select $c as value,sum(1) as count from sometable group by $c)")
val transformedString = selects.head + selects.tail.mkString(" a union "," union ","")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM