繁体   English   中英

添加scala列表的元素

[英]add elements of scala list

输入中有以下列表:

val listin= List("banana 20 20", "apple 50 20", "berry 10 10")

我想对列表中line的第二和第三元素求和,因此输出应如下所示:

val lisout=("banana 20 20 40", "apple 50 20 70", "berry 10 10 20")

我写了下面的代码

 def addInt(a:Int,b:Int):Int={
   a+b
 }

val listout= listin.map(_.split("\\s+")).collect{
  case e=> (e + " " + (addInt(e(1).toInt, e(2).toInt)).toString)}

但是我得到以下输出/错误:

List[String] = List([Ljava.lang.String;@7680c376 40, 
[Ljava.lang.String;@bf64054 70, [Ljava.lang.String;@4da833d 20)

请以任何优雅的方式致以诚挚的问候

字符串的分割是Array[String] ,因此collecte也是Array[String] 如果用另一个String调用+ ,Scala将调用数组的toString ,这是一个丑陋的表示。

一个最优雅的方法是将模式匹配与split函数配合使用。

listin.map { str =>
    val Array(_, numA, numB) = str.split("\\s+")
    str + " " + addInt(numA.toInt, numB.toInt)
}

一旦map(_.split(...)) ,就获得了一个数组列表,因此e将数组与split产生的字符串匹配。 如您所见,此数组的字符串表示形式非常难看。 尝试这样的事情:

listin.map { str =>
  val components = str.split("\\s+")
  str + " " + (components(1).toInt + components(2).toInt)
}

另外,您可以使用正则表达式来匹配整个字符串,而不是使用split 这里:

val P = """\w+\s+(\d+)\s+(\d+)""".r
listin.map { case s @ P(x, y) => s + " " + (x.toInt + y.toInt) }

给出相同的结果:

List(banana 20 20 40, apple 50 20 70, berry 10 10 20)

模式P意思是:标识符符号,后跟空格,后跟数字(第一个捕获的组),再跟空格,再捕获另一组数字。 map ,变量s匹配整个字符串, xy匹配两个捕获的带数字的组。

之所以会得到输出,是因为列表上的toString不会提取内容,而是输出类型信息。 您可能要使用mkString函数,但这并不是Scala最令人惊奇的部分。

您需要发现部分函数的真正魔力。

val listin= List("banana 20 20", "apple 50 20", "berry 10 10")

val listout= listin.map(_.split("\\s+")).map {
  case Array(a,b,c) => s"$a $b $c ${b.toInt + c.toInt}"
}

像元组和案例类一样,能够取消应用序列的内容是现代语言中的一个强大概念。

我还省略了addInt函数,并给出了交换中的字符串插值示例。 您会看到,通过在插值中使用花括号,您可以注入任意代码块,从而使许多字符串操作变得简洁。

最后,在这种情况下,map和collect可以互换使用,因为部分函数确实定义了整个函数,而当您想跳过与所有情况都不匹配的内容时,collect非常有用。 如果您想查看地图失败,只需在输入列表中输入“ egg 10”,而collect会跳过它。

您已经有了很好的答案。 我只想提供仅使用映射和字符串插值的简单答案

listin.map(x => s"$x ${(x.split("\\s+")(1).toInt + x.split("\\s+")(2).toInt)}")

您试图将字符串添加到数组对象,以便在列表中看到OBJECT_HASHCODE SUM

为了获得所需的输出,您必须将字符串添加到字符串,即将数组转换为字符串,然后再添加总和。 使用collect

listInput.map(_.split("\\s+")).collect{
  case e => e.mkString(" ")+" "+(e.apply(1).toInt+e.apply(2).toInt)
}    
//res3: List[String] = List(banana 20 20 40, apple 50 20 70, berry 10 10 20)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM