преобразовать число в int, если оно является целым числом, иначе преобразовать в число с плавающей точкой - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь извлечь число из строки, затем проверяю, является ли оно целым или двойным. Если это целое число, то я конвертирую число, используя toInt. Если это не так, преобразование в Double с использованием toDouble.

val str = 50 units
val num = str.split("\\D+").filter(_.nonEmpty)
val y = num(0).toDouble
val x = num(0).toInt
if (x==y) {
  x
  //print("int")
} else {
  y
  //print("double")
}

Вот код, который я пробовал. Проблема в том, что даже если условие истинно, я получаю число, преобразованное в удвоение. Кто-нибудь может решить эту проблему?

Ответы [ 3 ]

2 голосов
/ 20 июня 2019

1-ая проблема - Вы разделяетесь на нецифровые символы, поэтому оно разделяется на точку ., и вы никогда не получите правильное значение Double.

2-ая задача - Переменные x и y будут всегда равны, потому что они обе взяты из одной и той же строки цифр.50 == 50.0 всегда true.

3-я проблема - Даже если условие if всегда true и, следовательно, всегда возвращает значение Int в xрезультат if равен Double, поскольку оператор if должен возвращать один тип.Этот пытается вернуть Int или a Double, поэтому значение Int увеличивается до Double, так что типы совпадают.

Так что вы 'пытаться сделать это необоснованно.Вы хотите, чтобы это был один тип или другой.Система типов пытается навязать компромисс (Double).Если это неприемлемо, вы можете подумать об обёртывании ваших типов в Either.

val numPattern = "\\d*.?\\d+".r
val str = "50 units"
val dbl = numPattern.findFirstIn(str).fold(0.0)(_.toDouble)

val rslt :Either[Int,Double] = if (dbl.isValidInt) Left(dbl.toInt) else Right(dbl)
//rslt: Either[Int,Double] = Left(50)
0 голосов
/ 20 июня 2019

Ваш сплит неверен. В случае, если строка 50.2 units, num будет содержать 502. Вам нужно использовать правильное регулярное выражение (я проверяю только первое число в строке, и оно делится на " ", если оно существует).

Вы можете сделать это следующим образом (разбор и поиск, если это int или double)

val str = "50.2 units"
val numericRegex: String = ".*\\d+\\.?\\d+.*"
val numOT = Try((str.split(" ").filter(_.matches(numericRegex))).headOption.map(_.toDouble))

numOT match {
  case Success(numO) => 
    numO.fold {
      println(s"no number exist in $str")
    } { num =>
      if ((num % 1) == 0) { 
        println("int") 
      } else { 
        println("double") 
      }
    }
 case Failure(error) => println("an error $error occcurs")  
}

Вы можете играть с ним здесь

0 голосов
/ 20 июня 2019

Простой и хитрый

val res = if (num(0).contains('.')) num(0).toDouble else num(0).toInt

Или вы можете использовать регулярные выражения или scala.util.Try.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...