Как проверить, является ли строка десятичным числом в Scala
Я все еще довольно новичок в Scala, и я открываю новые и интересные способы для работы почти ежедневно, но они не всегда разумны и иногда уже существуют в языке как конструкция и я просто не знаю о них. Итак, с этой преамбулой, я проверяю, содержит ли данная строка целые числа, поэтому я делаю:
def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)
Это разумно или просто бесполезно глупо? Это там лучший способ? Лучше просто называть x.toInt и улавливать исключение, или это менее идиоматично? Есть ли преимущество/недостаток производительности для?
Ответы
Ответ 1
Попробуйте следующее:
def isAllDigits(x: String) = x forall Character.isDigit
forall
принимает функцию (в данном случае Character.isDigit
), которая принимает аргумент, который относится к типу элементов коллекции и возвращает a Boolean
; он возвращает true
, если функция возвращает true
для всех элементов в коллекции, а false
в противном случае.
Ответ 2
Вы хотите знать, является ли строка целым? Затем .toInt
он и поймает исключение. Вместо этого вы хотите знать, является ли строка целыми цифрами? Затем спросите одного из:
s.forall(_.isDigit)
s matches """\d+"""
Ответ 3
Вы также можете рассмотреть что-то вроде этого:
import scala.util.control.Exception.allCatch
def isLongNumber(s: String): Boolean = (allCatch opt s.toLong).isDefined
// or
def isDoubleNumber(s: String): Boolean = (allCatch opt s.toDouble).isDefined
Ответ 4
Вы можете просто использовать регулярное выражение для этого.
val onlyDigitsRegex = "^\\d+$".r
def isAllDigits(x: String) = x match {
case onlyDigitsRegex() => true
case _ => false
}
Или просто
def isAllDigits(x: String) = x.matches("^\\d+$")
И чтобы немного улучшить это, вы можете использовать шаблон pib my library, чтобы сделать его методом в вашей строке:
implicit def AllDigits(x: String) = new { def isAllDigits = x.matches("^\\d+$") }
"12345".isAllDigits // => true
"12345foobar".isAllDigits // => false
Ответ 5
import scala.util.Try
object NumCruncher {
def isShort(aString: String): Boolean = Try(aString.toLong).isSuccess
def isInt(aString: String): Boolean = Try(aString.toInt).isSuccess
def isLong(aString: String): Boolean = Try(aString.toLong).isSuccess
def isDouble(aString: String): Boolean = Try(aString.toDouble).isSuccess
def isFloat(aString: String): Boolean = Try(aString.toFloat).isSuccess
/**
*
* @param x the string to check
* @return true if the parameter passed is a Java primitive number
*/
def isNumber(x: String): Boolean = {
List(isShort(x), isInt(x), isLong(x), isDouble(x), isFloat(x))
.foldLeft(false)(_ || _)
}
}
Ответ 6
Try
может быть не оптимальным выбором по производительности, но в противном случае он опрятен:
scala> import scala.util.Try
scala> Try{ "123x".toInt }
res4: scala.util.Try[Int] = Failure(java.lang.NumberFormatException: For input string: "123x")
scala> Try{ "123x".toInt }.isSuccess
res5: Boolean = false
Ответ 7
@Ответ на Jesper находится на месте.
Do НЕ делать то, что я предлагаю ниже (объяснение следует)
Поскольку вы проверяете, является ли заданная строка числовой (состояния заголовка - десятичная), предполагается, что вы намерены сделать преобразование, если передатчик forall прошел.
Простая неявная область видимости сохранит колоссальные 9 нажатий клавиш; -)
implicit def str2Double(x: String) = x.toDouble
Почему это опасно
def takesDouble(x: Double) = x
Теперь компилятор разрешит takesDouble("runtime fail")
, так как неявный пытается преобразовать любую строку, которую вы используете в Double, с нулевой гарантией успеха, yikes.
неявные преобразования тогда кажутся более подходящими для ситуаций, когда допустимое значение по умолчанию предоставляется при ошибке преобразования (что не всегда так, поэтому подразумевается с осторожностью)
Ответ 8
Вот еще один:
import scala.util.Try
val doubleConverter: (String => Try[Double]) = (s: String) => Try{ s.map(c => if ((Character.isDigit(c) == true) || (c == '.')) Some(c) else None).flatten.mkString.toDouble }
val d1: Try[Double] = doubleConverter("+ 1234.0%")
val d2: Try[Double] = doubleConverter("+ 1234..0%")
Ответ 9
Начиная с Scala 2.13
мы можем использовать String::toDoubleOption
, чтобы определить, является ли строка десятичным числом или нет:
"324.56".toDoubleOption.isDefined // true
"4.06e3".toDoubleOption.isDefined // true
"9w01.1".toDoubleOption.isDefined // false
Аналогичная опция, чтобы определить, является ли String простым Int:
"324".toIntOption.isDefined // true
"à32".toIntOption.isDefined // false
"024".toIntOption.isDefined // true
Ответ 10
Основываясь на блестящем решении Jexter, в этом фрагменте кода я позабочусь об исключении NullPointerException, используя Option:
def isValidPositiveNumber(baseString: Option[String]): Boolean = baseString match {
case Some(code) => !code.isEmpty && (code forall Character.isDigit)
case None => false
}