首页 > 解决方案 > 如何使用@tailrec 连接 scala.collection.mutable.WrappedArray 中的字符串?

问题描述

我需要连接 Scala 中 WrappedArray 中存在的字符串。我能够在 的帮助下做到这一点,List但这不是我必须做的。我想要一个专门为 WrappedArray 设计的解决方案,并且在连接时可以添加/删除元素。我必须将此函数用作 udf 来通过 Spark SQL 转换数据collect_list。这就是我被迫使用 WrappedArray 的原因。

例如->

WrappedArray("I","love","coding")
Output : String = I : love : coding

这只是一个添加冒号的例子。在使用 Wrapped Array 的情况下,我在匹配时遇到了各种类型的问题。

import scala.annotation.tailrec

object tailRecursionString {

  def getString(ints :scala.collection.mutable.WrappedArray[String]): String = {
    @tailrec
    def sumAccumulator(ints: scala.collection.mutable.WrappedArray[String], accum: String): String = {
      ints match {
        case Nil :  => accum
        case x :: tail => sumAccumulator(tail, accum + x)
      }
    }
    sumAccumulator(ints, "[") + "]"
  }

  def main(args: Array[String]): Unit = {
    val list : scala.collection.mutable.WrappedArray[String] = Array("kumar","sambhav","is","a","good","boy")
    val sum = getString(list)
    println(sum)
  }

}

标签: scalaapache-sparkfunctional-programmingapache-spark-sql

解决方案


您的问题的原因是使用WrappedArraywhich has notunapply方法。模式匹配使用方法工作,您可以在scala 文档unapply中阅读更多相关信息。只需将 WrappedArray 替换为 Array 并匹配表达式即可:

@tailrec
def sumAccumulator(ints: Array[String], accum: String): String = {
  ints match {
    case Array()  => accum
    case _ => sumAccumulator(ints.tail, accum + ints.head)
  }
}

List有子类型::Nil。它们是案例类,案例类具有unapply编译器生成的方法。

简而言之,我尝试描述它是如何工作的:当编译器寻找提取(在模式匹配中)时,它会查看,发现它是and has方法::的子类型,如果返回正确的结果,它会选择这个分支。对于.ListunapplyunapplyNil


推荐阅读