Biorąc pod uwagę tablicę liczb całkowitych:

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

Chcę przekształcić tę tablicę w inną tablicę:

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

Czy mogę dodać warunek do funkcji redukcji?

Coś w tym stylu:

...
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
    }
})

...
1
Dmitry 3 kwiecień 2020, 14:12

4 odpowiedzi

Najlepsza odpowiedź

Możesz spróbować dalej:

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)

Co przyniesie pożądany rezultat: (-2, 1, -3, 10, -1, 4, -5, 4) Mam nadzieję że to pomoże!

0
Ivan Kurchenko 3 kwiecień 2020, 11:37
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)

Lub:

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)
1
esse 3 kwiecień 2020, 12:01

Nie jestem pewien, czy możesz użyć funkcji redukuj lub innej prostej wbudowanej funkcji, aby osiągnąć swój cel.

Możesz jednak napisać prostą funkcję rekurencyjną ogonową, która robi to, co chcesz (używa listy i dopasowywania wzorców):

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
  }

Oczywiście można to uprościć, używając listy jako danych wejściowych zamiast tablicy, ale w swoim pytaniu wspomniałeś konkretnie o tablicy.

0
Thomas Böhm 3 kwiecień 2020, 11:44

Prosty, rekurencyjny nieogonkowy:

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)
  }
}
0
Feyyaz 3 kwiecień 2020, 13:17