如何在Scala中检查字符串是否为十进制数

时间:2012-03-30 06:38:51

标签: scala

我仍然是Scala的新手,我几乎每天都在发现新的有趣的做事方式,但它们并不总是合理的,有时候已经存在于语言中作为构造而我只是不知道他们。所以,有了这个序言,我正在检查一个给定的字符串是否完全由数字组成,所以我在做:

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

这是明智的还是不必要的愚蠢?有更好的方法吗?调用x.toInt并捕获异常更好,还是不那么惯用?是否存在性能优势/缺点?

10 个答案:

答案 0 :(得分:88)

试试这个:

def isAllDigits(x: String) = x forall Character.isDigit

forall接受一个函数(在这种情况下为Character.isDigit),该函数接受一个类型为集合元素类型的参数并返回Boolean;如果函数为集合中的所有元素返回true,则返回true,否则返回false

答案 1 :(得分:32)

你想知道字符串是否是整数?然后.toInt它并捕获异常。你想知道字符串是否都是数字?然后问一个:

s.forall(_.isDigit)
s matches """\d+"""

答案 2 :(得分:22)

你也可以考虑这样的事情:

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

答案 3 :(得分:5)

你可以简单地使用正则表达式。

val onlyDigitsRegex = "^\\d+$".r

def isAllDigits(x: String) = x match {
  case onlyDigitsRegex() => true
  case _ => false
}

或者只是

def isAllDigits(x: String) = x.matches("^\\d+$")

为了改善这一点,您可以使用pimp my library模式使其成为字符串上的方法:

implicit def AllDigits(x: String) = new { def isAllDigits = x.matches("^\\d+$") }

"12345".isAllDigits // => true
"12345foobar".isAllDigits // => false

答案 4 :(得分:4)

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)(_ || _)
  }

}

答案 5 :(得分:2)

typedef struct node { char *name; int num; struct node *next; } Node; Node *head = NULL; int insertInOrder(char *newName, int favNum) { Node *current = head; Node *newNode; Node *tempNode; int nodeIn = 0; if (head == NULL) { head = malloc(sizeof(Node)); if(head == NULL){ fprintf(stderr, "ERROR: Out of memory\n"); return 1; } head->name = newName; head->num = favNum; head->next = NULL; } else { while (current != NULL) { if (strcmp(newName, current->name) == 0) { fprintf(stderr, "ERROR: Name already exists in the list\n"); return 1; } if (strcmp(newName, current->name) < 0) { tempNode = current->next; newNode = malloc(sizeof(Node)); if(newNode == NULL){ fprintf(stderr, "ERROR: Out of memory\n"); return 1; } newNode->name = newName; newNode->num = favNum; newNode->next = tempNode; current->next = newNode; nodeIn = 1; } current = current->next; } if(nodeIn == 0){ newNode = malloc(sizeof(Node)); if(newNode == NULL){ fprintf(stderr, "ERROR: Out of memory\n"); return 1; } newNode->name = newName; newNode->num = favNum; current->next = newNode; newNode->next = NULL; } } return 0; } 可能在性能方面不是最佳选择,但除此之外它很整洁:

Try

答案 6 :(得分:1)

@ Jesper的回答是现实。

执行我在下面建议的内容(解释如下)

由于您正在检查给定的字符串是否为数字(标题状态是否需要小数),因此假设您希望在forall guard通过时进行转换。

范围内的简单隐含将节省高达9个击键次数; - )

implicit def str2Double(x: String) = x.toDouble

为什么这很危险

def takesDouble(x: Double) = x

编译器现在将允许takesDouble("runtime fail"),因为隐式尝试将您使用的任何字符串转换为Double,并且没有成功的保证,为yikes。

隐式转换似乎更适合于在转换失败时提供可接受的默认值的情况(情况并非总是如此;因此请谨慎隐含)

答案 7 :(得分:0)

还有一个:

  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%")

答案 8 :(得分:0)

AndroidManifest.xml开始,我们可以使用String::toDoubleOption来确定字符串是否为十进制数字:

Scala 2.13

确定字符串是否为简单Int的类似选项:

"324.56".toDoubleOption.isDefined // true
"4.06e3".toDoubleOption.isDefined // true
"9w01.1".toDoubleOption.isDefined // false

答案 9 :(得分:0)

基于出色的Jexter解决方案,在这段代码中,我将使用Option处理NullPointerException:

    def isValidPositiveNumber(baseString: Option[String]): Boolean = baseString match {
        case Some(code) => !code.isEmpty && (code forall Character.isDigit)
        case None => false
      }