Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String Scala:遍历字符串的每个字符并使用模式匹配_String_Scala_Char_Pattern Matching_String Iteration - Fatal编程技术网

String Scala:遍历字符串的每个字符并使用模式匹配

String Scala:遍历字符串的每个字符并使用模式匹配,string,scala,char,pattern-matching,string-iteration,String,Scala,Char,Pattern Matching,String Iteration,我想我想做的很明显。对于string1中的每个字符,使用模式匹配打印某些内容。(我在那里有string2,因为我将使用string1的模式匹配来对string2执行一些操作并返回string2) 出于某种原因,我的代码只打印出“()” 还有,如何确保代码返回字符串。当我把代码放进终端时,它说:(string1:String)String=>Unit,我如何让它说(string1:String)String=>String def stringPipeline(string1: String) =

我想我想做的很明显。对于string1中的每个字符,使用模式匹配打印某些内容。(我在那里有string2,因为我将使用string1的模式匹配来对string2执行一些操作并返回string2)

出于某种原因,我的代码只打印出“()”

还有,如何确保代码返回字符串。当我把代码放进终端时,它说:(string1:String)String=>Unit,我如何让它说(string1:String)String=>String

def stringPipeline(string1: String) = (string2: String) => {

  for(c <- string1) {
    c match {
      case 'u' => "Upper Case"
      case 'r' => "reverse"
      case _ => "do something"
    }
  }
}
def stringPipeline(string1:String)=(string2:String)=>{
对于(c)“大写”
案例“r”=>“反向”
案例=>“做点什么”
}
}
}
编辑:

我只想指出我想对string2做什么:

def stringPipeline(string1: String) = (string2: String) => { 
    for(c <- string1) yield { 
        c match { 
            case 'U' => string2.toUpperCase 
            case 'r' => string2.reverse } } } 
def stringPipeline(string1:String)=(string2:String)=>{
对于(c)string2.toUpperCase
大小写'r'=>string2.reverse}
但它返回的是一个向量/字符串列表。我希望所有这些情况都适用于同一个string2对象。因此,如果我在“hello”上测试该方法,它应该返回“OLLEH”


谢谢

您在(…)的
之后忘记了
产量
,因此
的最后一个
简单地运行,扔掉体内的所有东西,最后返回一个单位
()

如果你想退货,你应该使用这样的东西:

def stringPipeline(string1: String) = (string2: String) => {
  for (c <- string1) yield {
    c match {
      case 'u' => "Upper Case"
      case 'r' => "reverse"
      case _ => "do something"
    }
  }
}
def stringPipeline(pattern : String) = {
  def handleString(s : String, restPattern : List[Char]) : String = {
     restPattern match{
      case hd :: tl => {
        hd match{
          case 'u' => handleString(s.toUpperCase(), tl)
          case 'r' => handleString(s.reverse, tl)
          case _ => handleString(s, tl)
        }
      }
      case Nil => s    
    }
  }    
  s : String => handleString(s, pattern.toList)
}
val s = "urx"
val fun = stringPipeline(s)
println(fun("hello"))
但现在的情况是,它既没有返回任何有意义的东西,也没有任何副作用

编辑:

更新:如果要将
string1
视为一系列操作,将
string2
视为要应用这些操作的“材料”,可以执行以下操作:

def stringPipeline(string1: String) = (string2: String) => {
  string1.foldLeft(string2) { 
    case (s, 'u') => s.toUpperCase
    case (s, 'r') => s.reverse
    case (_, x) => 
      throw new Error("undefined string manipulation: " + x)
  }
}
def stringPipeline(string1: String) = (string2: String) => {
    string1.foldLeft(string2)((s: String, c: Char) =>
        c match {
            case 'u' => s.toUpperCase
            case 'r' => s.reverse
            case _   => s
        }
    )
}

上面的操作如下:它从
string2
开始,然后将
string1
中的每个操作应用到迄今为止累积的所有转换的结果。

如果您的目标是接收一个函数,该函数对字符串执行模式,您可以这样做:

def stringPipeline(string1: String) = (string2: String) => {
  for (c <- string1) yield {
    c match {
      case 'u' => "Upper Case"
      case 'r' => "reverse"
      case _ => "do something"
    }
  }
}
def stringPipeline(pattern : String) = {
  def handleString(s : String, restPattern : List[Char]) : String = {
     restPattern match{
      case hd :: tl => {
        hd match{
          case 'u' => handleString(s.toUpperCase(), tl)
          case 'r' => handleString(s.reverse, tl)
          case _ => handleString(s, tl)
        }
      }
      case Nil => s    
    }
  }    
  s : String => handleString(s, pattern.toList)
}
val s = "urx"
val fun = stringPipeline(s)
println(fun("hello"))
此函数返回一个递归函数,该函数依次执行模式的一个字母,最后返回结果字符串

然后,您可以这样做:

def stringPipeline(string1: String) = (string2: String) => {
  for (c <- string1) yield {
    c match {
      case 'u' => "Upper Case"
      case 'r' => "reverse"
      case _ => "do something"
    }
  }
}
def stringPipeline(pattern : String) = {
  def handleString(s : String, restPattern : List[Char]) : String = {
     restPattern match{
      case hd :: tl => {
        hd match{
          case 'u' => handleString(s.toUpperCase(), tl)
          case 'r' => handleString(s.reverse, tl)
          case _ => handleString(s, tl)
        }
      }
      case Nil => s    
    }
  }    
  s : String => handleString(s, pattern.toList)
}
val s = "urx"
val fun = stringPipeline(s)
println(fun("hello"))
返回
OLLEH


但是,它不是一种迭代方法,而是一种递归方法(更适合Scala之类的函数式编程语言)。

如果将定义粘贴到Scala REPL中,您将看到您定义的函数类型是

stringPipeline: (string1: String)String => Unit
i、 e.一种函数,它以字符串
string1
作为输入,返回一个闭包,以第二个字符串string2作为输入,并返回
Unit
,类似于Java中的
void
,只有值
()

那么,为什么返回的闭包将
Unit
作为返回类型?其主体仅包含一个表达式:

for(c <- string1) {
    c match {
      case 'u' => "Upper Case"
      case 'r' => "reverse"
      case _ => "do something"
    }
}
对于
string1
中的每个可能的
c
,然后返回
()
。换句话说,
不允许其内部产生的值通过

如果要打印字符串“大写”,则需要编写

    case 'u' => println("Upper Case")
然后闭包的返回值仍然是
()
,但它的计算结果将打印
匹配
表达式中的字符串作为副作用

另一方面,如果不使用参数string2,为什么要引入它

编辑

由于循环内的函数输出用作循环下一个循环的输入,因此需要一个折叠函数,即类似以下内容:

def stringPipeline(string1: String) = (string2: String) => {
  string1.foldLeft(string2) { 
    case (s, 'u') => s.toUpperCase
    case (s, 'r') => s.reverse
    case (_, x) => 
      throw new Error("undefined string manipulation: " + x)
  }
}
def stringPipeline(string1: String) = (string2: String) => {
    string1.foldLeft(string2)((s: String, c: Char) =>
        c match {
            case 'u' => s.toUpperCase
            case 'r' => s.reverse
            case _   => s
        }
    )
}

您需要实现管道,这样它就可以折叠
ops
字符串的字符,每个字符都是管道中转换的一个阶段

从第一次折叠的
input
字符串开始,然后
ops
字符串的每个后续折叠将转换最后一次折叠的输出

现在,当在折叠
ops
字符串时遇到不同的字符时,只需添加不同的变换操作

def stringPipeline(ops: String) = (input: String) => {
  ops.toLowerCase.foldLeft(input)((str: String, op: Char) => op match {
    case 'u' =>
      println("Operator - 'u' :: Transforming - Upper Case")
      str.toUpperCase
    case 'r' =>
      println("Operator - 'r' :: Transforming - Reverse")
      str.reverse
    case _ =>
      println("Operator - 'unknown' :: Doing Nothing")
      str
  })
}

val pipeline1 = stringPipeline("ur")

val s1 = "abcde"

val s1p1 = pipeline1(s1)

// Operator - 'u' :: Transforming - Upper Case
// Operator - 'r' :: Transforming - Reverse
// s1p1: String = EDCBA

任何
对string2做点什么的例子吗?
?看起来我收到的大多数建议都很有效。但是出现了另一个问题。为了回答你的问题,我尝试做了如下操作:def stringPipeline(string1:String)=(string2:String)=>{for(c string2.toUpperCase'l'=>string2.toLowerCase}}}但是它返回一个向量/字符串列表。我希望所有这些案例都在同一个string2对象上工作,现在它变得比以前更不清晰了…1)您至少可以添加预期结果的类型吗?甚至不清楚是否要返回任何内容。2)对于什么
string1
您希望输出“OLLEH”在您的示例中?我想重复将string1中包含的每个指令应用于string2中包含的字符串,然后返回结果?因此输出将是一个字符串。因此,如果string1是“Ur”,string2是“hello”,我需要将string2中的每个字符大写,然后反转该字符串并输出“OLLEH”啊…这是一个关于
string2
string1
的折页。我明白了!这不是我想做的。我想我的问题有点含糊不清,我应该发布我真正想对string2做的事情。我想做一些类似于:def stringPipeline(string1:String)=(string2:String)=>{(c string2.toUpperCase'l'=>string2.toLowerCase}}}但它返回的是一个向量/字符串列表。我希望所有这些案例都处理相同的string2对象如果我理解正确,您希望将
string1
中包含的每个指令重复应用于
string2
中包含的字符串,并返回结果?在这种情况下,您想做什么:case=>“做点什么”?你说的“做点什么”是什么意思?那是一种伪代码对不起。我用string2.rever替换了“做点什么”