Подтвердить что ты не робот

Как проверить, является ли строка десятичным числом в Scala

Я все еще довольно новичок в Scala, и я открываю новые и интересные способы для работы почти ежедневно, но они не всегда разумны и иногда уже существуют в языке как конструкция и я просто не знаю о них. Итак, с этой преамбулой, я проверяю, содержит ли данная строка целые числа, поэтому я делаю:

def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)

Это разумно или просто бесполезно глупо? Это там лучший способ? Лучше просто называть x.toInt и улавливать исключение, или это менее идиоматично? Есть ли преимущество/недостаток производительности для?

4b9b3361

Ответ 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
      }