String Scala:遍历字符串的每个字符并使用模式匹配
我想我想做的很明显。对于string1中的每个字符,使用模式匹配打印某些内容。(我在那里有string2,因为我将使用string1的模式匹配来对string2执行一些操作并返回string2) 出于某种原因,我的代码只打印出“()” 还有,如何确保代码返回字符串。当我把代码放进终端时,它说:(string1:String)String=>Unit,我如何让它说(string1:String)String=>StringString 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) =
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替换了“做点什么”