2012-03-30 14 views
34

bir ondalık sayı olup olmadığını görmek için nasıl kontrol edin Hala oldukça Scala için yeni ve ben her zaman bir şeyler yapmak için yeni ve ilginç yollar keşfediyorum, ancak her zaman değil Mantıklı ve bazen bir dil olarak bir yapı olarak zaten var ve ben sadece onları bilmiyorum. Yani, bu önsözde, ben belirli bir dize tamamen rakamlardan oluşan olup olmadığını görmek için kontrol ediyorum, bu yüzden yapıyorum:Bir dize Scala

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

bu mantıklı ya da sadece gereksiz saçma? Daha iyi bir yolu var mı? Sadece x.toInt çağırmak ve istisnayı yakalamak daha mı yoksa daha az deyimsel mi? Ya bir performans yararı/dezavantajı var mı?

+1

Not Sorunuzun cevabının, 'String'in sadece rakam içerdiğini, ancak bir 'Int' veya' Long''a sığmayacak olup olmadığını belirleyeceğini. @Tvaroh tarafından verilen cevap, sonucun uygun sayısal türde "uydurulacağını" garanti edecektir. – Ralph

cevap

66

bu deneyin:

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

forall toplama elemanlarının türü olan bir argüman alır ve Boolean döndüren (bu durumda Character.isDigit olarak) bir işlev alır; işlev, koleksiyondaki tüm öğeler için true ve aksi halde false döndürürse, true değerini döndürür.

+0

Ah! parlak, istediğim özel sos, bunu dilde yapmak için bir yapı olduğuna inanmak zorundaydım! Şimdi, herhangi bir şey için benzer bir yapı olup olmadığını merak ediyorum, bu yüzden mantıksal AND azaltma yerine, mantıksal VEYA azaltma YA? – PlexQ

+1

@PlexQ, OR "var" –

+0

@PlexQ [Scala API belgeleri] 'ne bakın (http://www.scala-lang.org/docu/files/collections-api/collections.html) (özellikle trait 'Traversable Daha fazla bilgi için [Scala koleksiyon kütüphanesi] (http://www.scala-lang.org/docu/files/collections-api/collections.html) ile ilgili bu dokümanlar. – Jesper

3

Bunun için bir normal ifade kullanabilirsiniz.

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

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

Veya sadece

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

Ve bu biraz geliştirmek için, bu uygulamanın dize bir yöntem yapmak için Pimp My kütüphane desen kullanabilirsiniz:

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

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

Jesper en @ Cevap açık. Eğer kontrol ediyoruz yana verilen bir dize (başlık bir ondalık istediğiniz başka devletlerin) sayısal ise

Do

(açıklama aşağıda) aşağıda önerdiğim şey ne DEĞİL, varsayım yapmak niyetinde olduğunu forall bekçisi geçerse bir dönüşüm.

bu tehlikelidir Neden ;-)

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

bir kuyruklu 9 tuş vuruşları kurtaracak kapsamında Basit örtük

def takesDouble(x: Double) = x 

derleyici şu ana örtük denemeden beri takesDouble("runtime fail") sağlayacak Sıfır kullandığınız diziyi Double'e dönüştürün, sıfır garantiyle, yikes.

örtük dönüşümler sonra kabul edilebilir bir varsayılan değer dönüştürme hatası üzerinde sağlanan durumlara daha uygun görünmektedir (her zaman böyle değildir ki; dikkatli dolayısıyla örtük)

+0

Bilmekte fayda var, yine de gizli dönüşümler bulmaya çalışıyorum! – PlexQ

+0

evet, fark ettiğim zımni yazıyı yazarken, bir saniye bekle, bu çalışma zamanında yanlış gidebilir ;-) – virtualeyes

28

sen bilmek ister misiniz dize bir tamsayı ise ? Sonra .toInt ve istisna yakalamak. Bunun yerine, dizenin tüm basamaklar olup olmadığını bilmek ister misiniz?Sonra birini soruyorum:

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

Sonuncusu sadece dizenin herhangi bir rakam içerip içermediğini kontrol eder sanırım. Boş bir dize de "rakam" olarak sayılırsa, doğru ifade "" "^ \ d + $" "" veya "" "^ \ d * $" "" olacaktır. – Ixx

+1

@Ixx - Görüyorum ki Java regexlerinin çeşitli yöntemlerle nasıl çalıştığını anlamıyorsunuz. –

+0

Çeşitli yöntemlerle ne demek istiyorsun? Sadece \ d + görüyorum ve genellikle dizede bir yere rakamları kontrol ediyor. Ama evet, özellikle Java veya Scala'da regex ile çok fazla çalışmadım, bu yüzden regex'in^\ d + $ – Ixx

18
Ayrıca böyle bir şey düşünebilir

:

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 
+0

Bunu kullanarak ondalık sayıları ve yuvarlak sayıları birbirinden ayırmaktan nasıl bahsedersiniz? – dbau

+0

nice tek liner – javadba

+0

(allCatch opt s.toLong) .isDefined in Try (s.toLong) .isSuccess'ın aksine bir avantajı var mı? –

1

Try epeyce optimum seçim olmayabilir, ama aksi takdirde düzgün var:

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