【问题标题】:How to reduce positive elements in collection in scala?如何减少scala中收集的积极元素?
【发布时间】:2020-04-03 11:12:32
【问题描述】:

给定一个整数数组 nums:

-2,1,-3,4,6,-1,2,1,1,-5,4

我想把这个数组转换成另一个数组:

-2,1,-3,10,-1,4,-5,4

我可以在 reduce 函数中添加条件吗?

类似的东西:

...
val nums = Array(-2,1,-3,4,6,-1,2,1,1,-5,4)
val reduced = nums.reduce((x, y) => {
    if (x > 0 && y > 0){
        x + y
    }
})

...

【问题讨论】:

    标签: arrays scala collections


    【解决方案1】:
    scala> val nums = Array(-2,1,-3,4,6,-1,2,1,1,-5,4)
    nums: Array[Int] = Array(-2, 1, -3, 4, 6, -1, 2, 1, 1, -5, 4)
    
    scala> nums.foldLeft(List[Int]()){ 
             case (init :+ last, num) if last > 0 && num > 0 => init :+ (last + num)
             case (res, num) => res :+ num 
           }
    res0: List[Int] = List(-2, 1, -3, 10, -1, 4, -5, 4)
    

    或者:

    scala> def reduce(nums: Seq[Int]): Seq[Int] = nums match {
         |   case x1+:x2+:xs => if(x1>0 && x2>0) reduce((x1+x2)+:xs) else x1+:reduce(x2+:xs)
         |   case ns => ns
         | }
    def reduce(nums: Seq[Int]): Seq[Int]
    
    scala> reduce(nums)
    val res1: Seq[Int] = ArraySeq(-2, 1, -3, 10, -1, 4, -5, 4)
    

    【讨论】:

      【解决方案2】:

      你可以试试下一个:

      val result = Array(-2,1,-3,4,6,-1,2,1,1,-5,4).foldLeft(ListBuffer.empty[Int]) {
        case (result, item) if item < 0 => result :+ item
        case (result, item) if item > 0 => result.lastOption.filter(_ > 0).fold(result :+ item) { positiveSum =>
          result.update(result.size -1, positiveSum + item)
          result
        }
      }
      
      println(result)
      

      这将产生预期的结果:(-2, 1, -3, 10, -1, 4, -5, 4) 希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        我不确定您是否可以使用 reduce 或其他简单的内置函数来实现您的目标。

        但是,您可以编写一个简单的尾递归函数来满足您的需求(它使用列表和模式匹配):

        def sumPositives(arr: Array[Integer]): Array[Integer] = {
            @scala.annotation.tailrec
            def rec(list: List[Integer], acc: List[Integer]): List[Integer] = list match{
              case x :: y :: rest if x >= 0 && y >= 0 => rec(x+y :: rest, acc)
              case x :: y :: rest => rec(y :: rest, x :: acc)
              case x :: Nil => (x :: acc).reverse
              case Nil =>acc.reverse
            }
        
            rec(arr.toList, List()).toArray
          }
        

        当然,这可以通过使用列表而不是数组作为输入来简化,但在你的问题中你特别提到了一个数组。

        【讨论】:

          【解决方案4】:

          一个简单的非尾递归:

          def reducePositives(l: List[Int]): List[Int] = {
            l.span(_ > 0) match {
              case (Nil, Nil) => Nil
              case (Nil, np :: rest) => np :: reducePositives(rest)
              case (p, rest) => p.sum :: reducePositives(rest)
            }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-03-13
            • 2019-02-17
            • 2018-03-27
            • 1970-01-01
            相关资源
            最近更新 更多