我仍然是Scala的新手,我几乎每天都在发现新的有趣的做事方式,但它们并不总是合理的,有时候已经存在于语言中作为构造而我只是不知道他们。所以,有了这个序言,我正在检查一个给定的字符串是否完全由数字组成,所以我在做:
def isAllDigits(x: String) = x.map(Character.isDigit(_)).reduce(_&&_)
这是明智的还是不必要的愚蠢?有更好的方法吗?调用x.toInt并捕获异常更好,还是不那么惯用?是否存在性能优势/缺点?
答案 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
}