我认为我想做的事情非常明显。对于string1中的每个字符,使用模式匹配打印一些东西。 (我有string2,因为我将使用string1的模式匹配来对字符串2执行某些操作并返回String 2)
出于某种原因,我的代码只打印出"()"。
另外,我如何确保我的代码返回一个String。当我把代码放在终端时,它说:(string1:String)String =>单位,我该怎么说(string1:String)String =>串
def stringPipeline(string1: String) = (string2: String) => {
for(c <- string1) {
c match {
case 'u' => "Upper Case"
case 'r' => "reverse"
case _ => "do something"
}
}
}
编辑:
我想指出我想用string2做什么:
def stringPipeline(string1: String) = (string2: String) => {
for(c <- string1) yield {
c match {
case 'U' => string2.toUpperCase
case 'r' => string2.reverse } } }
但是它会返回一个矢量/字符串列表。我希望所有这些案例都在同一个string2对象上工作。因此,如果我在&#34;你好&#34;上测试方法,它应该返回&#34; OLLEH&#34;。
由于
答案 0 :(得分:1)
您在yield
之后忘记了for ( ... )
,因此最后一个for
只会运行,抛弃身体内的所有内容,最后返回一个单位()
。
如果你想要归还某些东西,你应该使用类似的东西:
def stringPipeline(string1: String) = (string2: String) => {
for (c <- string1) yield {
c match {
case 'u' => "Upper Case"
case 'r' => "reverse"
case _ => "do something"
}
}
}
这将为每个string2
提供某种“行动描述列表”。
如果你真的想立即print
,你可以这样做:
def stringPipeline(string1: String) = (string2: String) => {
for (c <- string1) {
println(c match {
case 'u' => "Upper Case"
case 'r' => "reverse"
case _ => "do something"
})
}
}
但现在的方式,它既没有返回任何有意义的东西,也没有任何副作用。
修改强>
更新:如果您希望将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)
}
}
以上内容执行以下操作:它以string2
开头,然后将string1
中的每个操作应用于到目前为止累积的所有转换的结果。
答案 1 :(得分:0)
如果你的目标是接收一个在字符串上执行模式的函数,你可以这样做:
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这样的函数式编程语言)。
答案 2 :(得分:0)
如果将定义粘贴到Scala REPL中,您将看到已定义的函数类型为
stringPipeline: (string1: String)String => Unit
即。一个函数,它接受一个字符串string1
作为输入,并返回一个闭包,将第二个字符串string2作为输入,并返回Unit
,它与Java中的void
类似,只有值{{ 1}}。
那么为什么返回的闭包有()
作为返回类型?它的主体只包含一个表达式:
Unit
for(c <- string1) {
c match {
case 'u' => "Upper Case"
case 'r' => "reverse"
case _ => "do something"
}
}
评估其内部表达式
for
为c match {
case 'u' => "Upper Case"
case 'r' => "reverse"
case _ => "do something"
}
中的每个可能的c
,然后返回string1
。换句话说,()
不允许在其中产生值。
如果你想打印字符串&#34;大写&#34;你需要写
for
然后闭包的返回值仍为 case 'u' => println("Upper Case")
,但其评估将打印()
表达式中的字符串作为副作用。
另外,如果你不使用它,为什么要引入参数string2?
修改强>
由于循环内部函数的输出用作循环的下一个循环的输入,因此需要折叠函数,例如:
match
答案 3 :(得分:0)
您需要实现管道,使其折叠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