【问题标题】:Scala returning a function: multiple nested functionsScala返回一个函数:多个嵌套函数
【发布时间】:2018-07-16 00:21:30
【问题描述】:

我正在尝试创建一个函数,该函数将返回另一个函数,该函数将执行多个字符串操作(由给定选项确定): 选项有U(大写)、l(小写)T(标题大小写)s(排序)r(反向)和*(删除所有空格)。

现在,我拥有的代码将采用上述选项之一(因此,Us 等)并返回正确的结果。我想要的是stringPipeline("Us*") 应该返回一个函数,它将字符串转换为大写,对其进行排序并删除所有空格。

我不知道如何修改我的函数以适应多个选项。

def stringPipeline(Option:String) = (str:String) => {
    val UpperCase = () => str.toUpperCase
    val LowerCase = () => str.toLowerCase
    val titleCase = () => str.split(' ').map(_.capitalize).mkString(" ")
    val reverse = () => str.reverse
    val sortChars = () => str.sorted
    val replaceChar = () => str.replaceAll("\\s","")
    Option match {
        case "U" => UpperCase()
        case "l" => LowerCase()
        case "T" => titleCase()
        case "r" => reverse()
        case "s" => sortChars()
        case "*" => replaceChar()
    }        
}

我尝试使用 && 运算符(不起作用)、+ 运算符(调用这两个函数)并执行类似 reverse(UpperCase()) 的操作,但会导致编译器错误。

【问题讨论】:

    标签: scala nested-function


    【解决方案1】:

    您可以使用foldLeft 使用一个单独的函数递归地应用字符串上的所有运算符,该函数一次采用一个选项。

    def stringPipeline(ops: String) = (str: String) => {
      def applyOp(str: String, op: String) = op match {
        case "U" => str.toUpperCase
        case "l" => str.toLowerCase
        case "T" => str.split(' ').map(_.capitalize).mkString(" ")
        case "r" => str.reverse
        case "s" => str.sorted
        case "*" => str.replaceAll("\\s","")
      }
    
      ops.split("").foldLeft(str)(applyOp)
    }
    

    用字符串测试:

    val str = stringPipeline("Us*")("age bfh dc")
    println(str)
    

    会给出预期的结果

    ABCDEFGH
    

    【讨论】:

      【解决方案2】:

      另一种方法是生成复合函数。您可以尝试使用 andThen 来组合函数。例如:

      scala> def inputStringPipeline(inputStr: String): String => String = {
           |     val upperCase = (input: String) => input.toUpperCase
           |     val lowerCase = (input: String) => input.toLowerCase
           |     val titleCase = (input: String) => input.split(' ').map(_.capitalize).mkString(" ")
           |     val reverse = (input: String) => input.reverse
           |     val sortChars = (input: String) => input.sorted
           |     val replaceChar = (input: String) => input.replaceAll("\\s", "")
           | 
           |     val emptyFunc: String => String = (input: String) => input
           |     inputStr.foldLeft(emptyFunc) {
           |       case (funcAcc, present) =>
           |         val newFunc = present.toString match {
           |           case "U" => upperCase
           |           case "l" => lowerCase
           |           case "T" => titleCase
           |           case "r" => reverse
           |           case "s" => sortChars
           |           case "*" => replaceChar
           |         }
           | 
           |         funcAcc andThen newFunc
           |     }
           | 
           | }
      inputStringPipeline: (inputStr: String)String => String
      
      scala> val input = "Us*"
      input: String = Us*
      
      scala> val func = inputStringPipeline(input)
      func: String => String = scala.Function1$$Lambda$1061/1593722877@5ef7ae2f
      
      scala> val str = func("age bfh dc")
      str: String = ABCDEFGH
      
      scala> println(str)
      ABCDEFGH
      

      这样,将为给定的输入字符串操作生成一个新函数,并且可以与任意数量的字符串一起使用。这将通过创建一次复合函数并再次使用它来节省时间。

      【讨论】:

        猜你喜欢
        • 2021-12-21
        • 1970-01-01
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-20
        • 1970-01-01
        相关资源
        最近更新 更多