String 如何在Scala中以功能性方式对照符号白名单检查字符串?

String 如何在Scala中以功能性方式对照符号白名单检查字符串?,string,scala,String,Scala,我需要保证字符串只包含允许的符号。现在我这样做: def isCorrect(s: String, allowedChars: String): Boolean = { s.distinct.foreach(c => { if (!allowedChars.contains(c)) return false }) true } 不用说,这看起来不太漂亮。有没有更好、更实用的方法 def isCorrect(s:String, allowedChars:S

我需要保证字符串只包含允许的符号。现在我这样做:

def isCorrect(s: String, allowedChars: String): Boolean = {
  s.distinct.foreach(c => {
    if (!allowedChars.contains(c))
      return false
  })

  true
}
不用说,这看起来不太漂亮。有没有更好、更实用的方法

def isCorrect(s:String, allowedChars:String):Boolean = { 
        s.forall{allowedChars.contains(_)}
    }
或者,更简洁地说,按照@ziggystar的建议:

def isCorrect(s: String, allowedChars: Seq[Char]) = s forall allowedChars.contains

我不知道这是否是最实用的方法,但你可以这样做:

def isCorrect(s: String, allowedChars: String): Boolean = {
    return s.distinct.forall(c => allowedChars.contains(c))
}

不同的实际上是不必要的。

对于记录,您可以通过不将自己限制为字符串来使其更通用,并通过切换参数顺序和使用两个参数列表来使其更实用(在我看来)。我是这样写的:

def isCorrect[A](allowed: Set[A])(s: Seq[A]) = s forall allowed
现在,您可以将此方法视为函数,并“部分应用”它以创建更专门的函数:

val isDigits = isCorrect("0123456789".toSet) _
val isAs = isCorrect(Set('A')) _
它允许您执行以下操作:

scala> isDigits("218903")
res1: Boolean = true

scala> isAs("218903")
res2: Boolean = false

scala> isDigits("AAAAAAA")
res3: Boolean = false

scala> isAs("AAAAAAA")
res4: Boolean = true

或者您仍然可以使用类似于
isCorrect(“abcdr.toSet”)(“abracadabra”)
的功能,但使用了regexp:

def isCorrect(s: String, allowedChars: String): Boolean =
  s.matches ("^["+ allowedChars +"]*$")
<> P>因为正则表达式经常被优化,所以我会在性能关键代码中考虑这种方法——不是没有测试、测量,也许是用预编译的模式——如果适合于手头的问题。p>
随着功能口味的增加,我看到了Travis代码。

谢谢。既然你们都给出了一个正确的答案,尽管你们给出的比较早,但我希望你们不会介意我接受罗德里戈的答案,让他获得一些声誉积分。尽管我认为我会坚持使用string.forall variant,我非常感谢你们的回答。如果可以,我会投两次甚至更多的票。。。谢谢,特拉维斯。刚刚醒来,钱掉了,宾,谢谢你提供了一个具体的“有用的”部分应用程序示例,特拉维斯。@Travis Tyvm发布了这个答案。我对部分函数的效用的理解很模糊。您的示例非常清晰、简洁,至少对我来说,这是我在大多数配置文件(如处理)中遇到的一种非常常见的模式。您可以省略
return
和大括号。您也可以只写
allowedChars.contains
作为括号的内容<代码>…=s、 对于所有(allowedChars.contains)@Ziggystar,这似乎不正确
def isCorrect(s:String,allowedChars:String):Boolean={s.forall(allowedChars.contains)}
gives
错误:类型不匹配;found:java.lang.CharSequence=>Boolean required:Char=>Boolean s.forall(allowedChars.contains)}
@ziggstar的意思可能是:“def isCorrect(s:String,allowedChars:Seq[String])=s.forall(allowedChars.contains)”,这很酷,我经常忘记可以隐式地将“\u1”传递给函数,比如“list foreach println”@virtualeyes,我知道你的意思是
allowChars:Seq[Char]
在那里(它确实起作用并保留兼容的签名)。用修改过的答案更新了我的答案version@Paul对,我只是粘贴了REPL并制作了一个Seq[String]来编译它,没有注意实际的函数要求,允许使用字符;-)。。如果allowedChars包含']'(或'^'作为第一个字符,则会以有趣的方式出错。是的,这是真的。使用
s.matches(“^[”+escape(allowedChars)+“]*$”)
escape
必须为此编写。:)啊!这就是一个例子:有些人在遇到问题时,会想“我知道,我会使用正则表达式”,现在他们有两个问题。