【问题标题】:add elements of scala list添加scala列表的元素
【发布时间】:2018-05-10 21:45:39
【问题描述】:

我在输入中有以下列表:

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

我想将列表中的第二个和第三个元素相加,所以输出应该是这样的:

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)

请以优雅的方式解决此问题 最好的问候

【问题讨论】:

    标签: scala list sum


    【解决方案1】:

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

    最优雅的方法是使用split 函数的模式匹配。

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

    【讨论】:

      【解决方案2】:

      您得到的输出是因为列表上的 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 会跳过它。

      【讨论】:

        【解决方案3】:

        只要您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用数字匹配两个捕获的组。

        【讨论】:

          【解决方案4】:

          您已经得到了很好的答案。我只想提供一个简单的答案,只使用地图和字符串插值

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

          【讨论】:

            【解决方案5】:

            您正在尝试向数组对象添加一个字符串,以便在列表中看到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)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-09-06
              • 2013-11-05
              • 2016-02-01
              • 2017-06-23
              • 2020-09-02
              • 2014-06-10
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多