加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

字符串 – 从同一行读取多个输入Scala方式

发布时间:2020-12-16 19:06:56 所属栏目:安全 来源:网络整理
导读:我试图使用readInt()从同一行读取两个整数,但这不是它的工作原理. val x = readInt()val y = readInt() 输入1 727我在运行时得到以下异常: Exception in thread "main" java.lang.NumberFormatException: For input string: "1 727" at java.lang.NumberFor
我试图使用readInt()从同一行读取两个整数,但这不是它的工作原理.

val x = readInt()
val y = readInt()

输入1 727我在运行时得到以下异常:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1 727"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at scala.collection.immutable.StringLike$class.toInt(StringLike.scala:231)
    at scala.collection.immutable.StringOps.toInt(StringOps.scala:31)
    at scala.Console$.readInt(Console.scala:356)
    at scala.Predef$.readInt(Predef.scala:201)
    at Main$$anonfun$main$1.apply$mcVI$sp(Main.scala:11)
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:75)
    at Main$.main(Main.scala:10)
    at Main.main(Main.scala)

我使用readf可以让程序工作,但对我来说似乎很尴尬和丑陋:

val (x,y) = readf2("{0,number} {1,number}")
  val a = x.asInstanceOf[Int]
  val b = y.asInstanceOf[Int]
  println(function(a,b))

有人建议我只使用Java的Scanner类(Scanner.nextInt()),但是在Scala中有一个很好的惯用方法吗?

编辑:
我的解决方案遵循范例的例子:

val Array(a,b) = readLine().split(" ").map(_.toInt)

跟进问题:如果在String中混合了类型,你将如何提取它? (说一个字,一个int和一个百分比作为一个双)

解决方法

如果你的意思是如何将val s =“Hello 69 13.5%”转换成(String,Int,Double),那么最明显的方法是

val tokens = s.split(" ")
(tokens(0).toString,tokens(1).toInt,tokens(2).init.toDouble / 100)
 // (java.lang.String,Double) = (Hello,69,0.135)

或者如前所述,您可以使用正则表达式进行匹配:

val R = """(.*) (d+) (d*.?d*)%""".r
s match {
  case R(str,int,dbl) => (str,int.toInt,dbl.toDouble / 100)
}

如果你真的不知道什么数据将在String中,那么可能没有太多的理由将它从一个字符串转换成它所代表的类型,因为你如何使用可能是一个字符串和可能的东西在Int?不过,你可以这样做:

val int = """(d+)""".r
val pct = """(d*.?d*)%""".r

val res = s.split(" ").map {
  case int(x) => x.toInt
  case pct(x) => x.toDouble / 100
  case str => str
} // Array[Any] = Array(Hello,0.135)

现在做任何有用的事情,你需要根据类型匹配你的值:

res.map {
  case x: Int => println("It's an Int!")
  case x: Double => println("It's a Double!")
  case x: String => println("It's a String!")
  case _ => println("It's a Fail!")
}

或者如果您想进一步了解,您可以定义一些提取器,这些提取器将为您进行转换:

abstract class StringExtractor[A] {
  def conversion(s: String): A
  def unapply(s: String): Option[A] = try { Some(conversion(s)) } 
                                      catch { case _ => None }
}

val intEx = new StringExtractor[Int] { 
  def conversion(s: String) = s.toInt 
}
val pctEx = new StringExtractor[Double] { 
   val pct = """(d*.?d*)%""".r
   def conversion(s: String) = s match { case pct(x) => x.toDouble / 100 } 
}

并使用:

"Hello 69 13.5%".split(" ").map {
  case intEx(x) => println(x + " is Int: "    + x.isInstanceOf[Int])
  case pctEx(x) => println(x + " is Double: " + x.isInstanceOf[Double])
  case str      => println(str)
}

版画

Hello
69 is Int: true
0.135 is Double: true

当然,你可以让任何你想要的东西(货币助记符,名字用’J’,URL来)匹配,并返回你想要的任何类型.您不仅限于匹配字符串,如果不是使用StringExtractor [A],则可以使其提取器[A,B].

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读