Soru Bir Scala String'in Double (Çift) olarak mı ayrıştırılabildiğini nasıl bulursunuz?


Scala'da bir dizim olduğunu varsayalım ve bunun iki katını ayrıştırmak istiyorum.

Biliyorum, sadece arayabilirim toDouble ve daha sonra bu başarısız olursa java num formatı istisna yakalamak, ancak bunu yapmak için daha temiz bir yolu var mı? Örneğin, eğer bir parseDouble döndürülen işlev Option[Double] Bu uygun olurdu.

Bunu standart kütüphanede zaten varsa kendi koduma koymak istemiyorum ve sadece yanlış yerde arıyorum.

Sağladığınız herhangi bir yardım için teşekkürler.


44
2018-03-03 00:11


Menşei




Cevaplar:


Ya da sadece

def parseDouble(s: String) = try { Some(s.toDouble) } catch { case _ => None }

Süslü versiyonu:

case class ParseOp[T](op: String => T)
implicit val popDouble = ParseOp[Double](_.toDouble)
implicit val popInt = ParseOp[Int](_.toInt)
// etc.
def parse[T: ParseOp](s: String) = try { Some(implicitly[ParseOp[T]].op(s)) } 
                                   catch {case _ => None}

scala> parse[Double]("1.23")
res13: Option[Double] = Some(1.23)

scala> parse[Int]("1.23")
res14: Option[Int] = None

scala> parse[Int]("1")
res15: Option[Int] = Some(1)

46
2018-03-03 01:02



Gerçekten yakalamalısın NonFatal(_)değil, sadece _. - rightfold
Kullanmayı tercih etmelisin Try işlevi. @Jeff Schwab yanıtına bakınız. - Moebius


Scalaz bir uzatma yöntemi sağlar parseDouble üzerinde Strings, bir tür değeri verir Validation[NumberFormatException, Double].

scala> "34.5".parseDouble
res34: scalaz.Validation[NumberFormatException,Double] = Success(34.5)

scala> "34.bad".parseDouble
res35: scalaz.Validation[NumberFormatException,Double] = Failure(java.lang.NumberFormatException: For input string: "34.bad")

Onu dönüştürebilirsiniz Option eğer gerekliyse.

scala> "34.bad".parseDouble.toOption
res36: Option[Double] = None

30
2018-03-03 04:13



Bu performansın performansı, nasıl bir araya getirilmiş varsayılan kitaplık uygulamasına göre karşılaştırılır? Try()? - NightWolf
@Gece kurdu, Try Bu cevabı yazdığım zaman yoktu. Bu bağlamda, her iki yaklaşım da aynı şekilde çalışır ve performans aynı olmalıdır. - missingfaktor
@NightWolf, sanırım Scalaz o zamandan beri Validation ve benzer fakat daha fazla ses özelliklerine sahip başka bir tip tanıttı. Yine de yanlış olabilirim. Bir süredir kullanmadım. - missingfaktor


scala> import scala.util.Try
import scala.util.Try

scala> def parseDouble(s: String): Option[Double] = Try { s.toDouble }.toOption
parseDouble: (s: String)Option[Double]

scala> parseDouble("3.14")
res0: Option[Double] = Some(3.14)

scala> parseDouble("hello")
res1: Option[Double] = None

19
2018-06-18 00:25





Kullanmayı deneyebilirsiniz util.control.Exception.catching hangi bir döndürür Either yazın.

Bu yüzden aşağıdakileri kullanarak bir sol sarma a NumberFormatException ya da doğru bir sarma Double

import util.control.Exception._

catching(classOf[NumberFormatException]) either "12.W3".toDouble

10
2018-03-03 01:12





Ne yazık ki, bu standart kütüphanede değil. İşte kullandığım şey:

class SafeParsePrimitive(s: String) {
  private def nfe[T](t: => T) = {
    try { Some(t) }
    catch { case nfe: NumberFormatException => None }
  }
  def booleanOption = s.toLowerCase match {
    case "yes" | "true" => Some(true)
    case "no" | "false" => Some(false)
    case _ => None
  }
  def byteOption = nfe(s.toByte)
  def doubleOption = nfe(s.toDouble)
  def floatOption = nfe(s.toFloat)
  def hexOption = nfe(java.lang.Integer.valueOf(s,16))
  def hexLongOption = nfe(java.lang.Long.valueOf(s,16))
  def intOption = nfe(s.toInt)
  def longOption = nfe(s.toLong)
  def shortOption = nfe(s.toShort)
}
implicit def string_parses_safely(s: String) = new SafeParsePrimitive(s)

6
2018-03-03 05:05





Scala’da değil, temel Java’da bile böyle bir şey yok.

İşte bunu yapan bir parça kodu istisnasızolsa da:

def parseDouble(s: String)(implicit nf: NumberFormat) = {
    val pp = new ParsePosition(0)
    val d = nf.parse(s, pp)
    if (pp.getErrorIndex == -1) Some(d.doubleValue) else None
}

Kullanımı:

implicit val formatter = NumberFormat.getInstance(Locale.ENGLISH)

Console println parseDouble("184.33")
Console println parseDouble("hello, world")

6
2018-03-03 00:42





Genellikle "yerinde" ile giderdim.

def strTimesTen (s: String) = for (d <- Try(s.toDouble)) yield d * 10

strTimesTen("0.1") match {
    Success(d) => println( s"It is $d" )
    Failure(ex) => println( "I've asked for a number!" )
}

Unutmayın ki, daha fazla hesaplama yapabilir ve herhangi bir istisna bir Arızaya dönüşebilir (örn.). AFAIK, bu bir dizi güvenilmez işlemlerin işleyişinin deyimidir.


1
2018-05-04 18:40



Opps, işaret ettiğin için teşekkürler, düzeltildi =) - Maverick
Scala için yeni olduğum için yanılıyor olabilirim ama bu derlemeyi yapmak için a) scala.util'i içe aktardığına inanıyorum. {Dene, Başarı, Başarısızlık} ve 'Başarı' kelimelerinden önce 'vaka' sözcüğünü ekleyin. ve 'Hata' - E Shindler