【问题标题】:Is there a better way of converting Iterator[char] to Seq[String]?有没有更好的方法将 Iterator[char] 转换为 Seq[String]?
【发布时间】:2018-03-15 14:51:50
【问题描述】:

以下是我用来将 Iterator[char] 转换为 Seq[String] 的代码。

val result = IOUtils.toByteArray(new FileInputStream (new File(fileDir)))
val remove_comp = result.grouped(11).map{arr => arr.update(2, 32);arr}.flatMap{arr => arr.update(3, 32); arr}
val convert_iter = remove_comp.map(_.toChar.toString).toSeq.mkString.split("\n")
val rdd_input = Spark.sparkSession.sparkContext.parallelize(convert_iter)

val 文件目录:

12**34567890
12@@34567890
12!!34567890
12¬¬34567890
12
'34567890

我对这段代码不满意,因为数据量很大,转换为字符串最终会得到堆空间。

val convert_iter = remove_comp.map(_.toChar)
convert_iter: Iterator[Char] = non-empty iterator

有没有更好的编码方式?

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    通过完全忽略关于空字符串等的极端情况,我将从以下内容开始:

    val test = Iterable('s','f','\n','s','d','\n','s','v','y')
    
    val (allButOne, last) = test.foldLeft( (Seq.empty[String], Seq.empty[Char]) ) {
      case ((strings, chars), char) =>
        if (char == '\n')
          (strings :+ chars.mkString, Seq.empty)
        else
          (strings, chars :+ char)
    }
    
    val result = allButOne :+ last.mkString
    

    我相信它可以变得更优雅,并且可以更好地处理极端情况(一旦你定义了你想要处理它们),但我认为这是一个很好的起点。

    但老实说,我并不完全确定您想要实现什么。我只是猜想您想将除以\n 的字符组合在一起并将它们转换为Strings。

    【讨论】:

    • 首先,我想删除第二个和第三个字节。二、将文本(新行分隔的字段分隔符)转换为RDD
    【解决方案2】:

    查看您的代码,我发现您正在尝试替换特殊字符,例如 **@@ 等以下数据

    12**34567890 12@@34567890 12!!34567890 12¬¬34567890 12 '34567890

    为此,您可以使用 sparkContext textFile 读取数据并使用正则表达式 replaceAllIn

    val pattern = new Regex("[¬~!@#$^%&*\\(\\)_+={}\\[\\]|;:\"'<,>.?` /\\-]")
    val result = sc.textFile(fileDir).map(line => pattern.replaceAllIn(line, ""))
    

    您应该将result 设置为RDD[String],这也是一个迭代器

    1234567890
    1234567890
    1234567890
    1234567890
    12
    34567890
    

    更新

    如果有\n\r在文本之间在第3和第4位并且如果结果都是固定长度的10位文本那么你可以使用sparkContextwholeTextFiles api 并使用以下 regex as

    val pattern = new Regex("[¬~!@#$^%&*\\(\\)_+={}\\[\\]|;:\"'<,>.?` /\\-\r\n]")
    val result = sc.wholeTextFiles(fileDir).flatMap(line => pattern.replaceAllIn(line._2, "").grouped(10))
    

    你应该得到输出为

    1234567890
    1234567890
    1234567890
    1234567890
    1234567890
    

    希望回答对你有帮助

    【讨论】:

    • 正则表达式将不起作用,因为特殊字符可以是新行
    • 你的行是固定长度的吗?因为你使用了 grouped(11) 这意味着它们是固定长度的,不是吗?
    • 是的,它们是固定长度的,其中 2 个字节可以是任何东西
    • @Aavik 我已经更新了答案 :) 请立即查看
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2014-07-27
    • 2022-09-23
    相关资源
    最近更新 更多