Совместимость шаблонов с нечувствительными к строкам
match (str) {
case "String1" => ???
case "String2" => ???
}
Это соответствие с учетом регистра. Как написать нечувствительность к регистру? Я знаю, что могу вызвать toLowerCase для каждой ветки, но я хочу более элегантное решение.
Ответы
Ответ 1
Основной подход:
Вы можете использовать Защиты шаблонов и Регулярные выражения
str match {
case s if s matches "(?i)String1" => 1
case s if s matches "(?i)String2" => 2
case _ => 0
}
Сложный метод:
Имплициты с Интерполяция строк и Regex
implicit class CaseInsensitiveRegex(sc: StringContext) {
def ci = ( "(?i)" + sc.parts.mkString ).r
}
def doStringMatch(str: String) = str match {
case ci"String1" => 1
case ci"String2" => 2
case _ => 0
}
Пример использования примера в REPL:
scala> doStringMatch("StRINg1")
res5: Int = 1
scala> doStringMatch("sTring2")
res8: Int = 2
Ответ 2
Другой подход, который не зависит от регулярных выражений или интерполяторов:
implicit class StringExtensions(val s: String) extends AnyVal {
def insensitive = new {
def unapply(other: String) = s.equalsIgnoreCase(other)
}
}
val test1 = "Bye".insensitive
val test2 = "HELLo".insensitive
"Hello" match {
case test1() => println("bad!")
case test2() => println("sweet!")
case _ => println("fail!")
}
Вот еще один способ использования интерполяторов, но не регулярное выражение:
implicit class StringInterpolations(sc: StringContext) {
def ci = new {
def unapply(other: String) = sc.parts.mkString.equalsIgnoreCase(other)
}
}
"Hello" match {
case ci"Bye" => println("bad!")
case ci"HELLO" => println("sweet!")
case _ => println("fail!")
}
Вышеприведенное может также использоваться для сопоставления шаблонов внутри классов case, например:
case class Dog(name: String)
val fido = Dog("FIDO")
fido match {
case Dog(ci"fido") => "woof"
case _ => "meow :("
}
Ответ 3
Простое решение:
val str = "string1"
str toUpperCase match (str) {
case "STRING1" => ???
case "STRING2" => ???
}