【问题标题】:How to properly iterate over Array[String]?如何正确迭代 Array[String]?
【发布时间】:2019-11-02 16:17:12
【问题描述】:

我在 scala 中有一个函数,我向它发送参数,我这样使用它:

val evega = concat.map(_.split(",")).keyBy(_(0)).groupByKey().map{case (k, v) => (k, f(v))}

我的函数 f 是:

val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
implicit val localDateOrdering: Ordering[LocalDate] = Ordering.by(_.toEpochDay)
def f(v: Array[String]): Int = {
  val parsedDates = v.map(LocalDate.parse(_, formatter))
  parsedDates.max.getDayOfYear - parsedDates.min.getDayOfYear}

这是我得到的错误:

 found   : Iterable[Array[String]]
 required: Array[String]

我已经尝试过使用:

val evega = concat.map(_.split(",")).keyBy(_(0)).groupByKey().map{case (k, v) => (k, for (date <- v) f(date))}

但我遇到大量错误。

为了得到更好的图片,concat中的数据是:

1974,1974-06-22
1966,1966-07-20
1954,1954-06-19
1994,1994-06-27
1954,1954-06-26
2006,2006-07-04
2010,2010-07-07
1990,1990-06-30
...

它是 RDD[String] 类型。 我怎样才能正确地对其进行迭代并从该函数 f 中获取单个 Int?

【问题讨论】:

  • 你能提供一些示例数据吗?如果人们知道您正在处理的数据的格式,这将更容易回答。具体来说concat的内容结构。

标签: scala apache-spark rdd


【解决方案1】:

管道旁边的 RDD 类型是:

  • concat.map(_.split(",")) 给出RDD[Array[String]]
    • 例如Array("1954", "1954-06-19")
  • concat.map(_.split(",")).keyBy(_(0))RDD[(String, Array[String])]
    • 例如("1954", Array("1954", "1954-06-19"))
  • concat.map(_.split(",")).keyBy(_(0)).groupByKey()RDD[(String, Iterable[Array[String]])]
    • 例如Iterable(("1954", Iterable(Array("1954", "1954-06-19"), Array("1954", "1954-06-24"))))

因此当你最后map时,值的类型是Iterable[Array[String]]

由于您的输入是"1974,1974-06-22",因此解决方案可能包括用map 替换您的keyBy 转换:

input.map(_.split(",")).map(x => x(0) -> x(1)).groupByKey().map{case (k, v) => (k, f(v))}

确实,.map(x =&gt; x(0) -&gt; x(1))(而不是.map(x =&gt; x(0) -&gt; x)keyBy(_(0)) 是语法糖)将为拆分数组的第二个元素而不是数组本身提供值。因此在第二步中提供RDD[(String, String)] 而不是RDD[(String, Array[String])]

【讨论】:

  • 确实,您可以将v 转换为Arrayv.toArray。但是对于您的函数来说,接受可迭代以避免内存不足问题可能更安全。
  • 我已经试过了,我得到了这个错误:org.apache.spark.SparkException: Task not serializable
  • 这是另外一回事,解决了第一个问题后要解决的下一个问题;现在代码编译到f 的调用。它很可能来自您对DateTimeFormatter 的使用。
  • 是的,您将无法在您的 repl 上复制它。这发生在运行时,当您在驱动程序上初始化一个变量,然后尝试在其中一个工作人员上使用它。如果需要,请打开一个新问题,因为它与该问题的初始问题相去甚远。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-02
  • 2015-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多