Проценты округления в scala и общее количество должно соответствовать 100 - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть последовательность кортежей scala, как показано ниже

seqOfTuples: List[(String, Double)] = List((a,25.52), (a,25.54), (a,48.94), (b,25.52), (b,25.54), (b,48.94))

Я пытаюсь округлить второе значение в этих кортежах до одного десятичного числа и приравнять их к сумме 100 (добавляя остатокдробь до последнего числа) для любого заданного первого значения.

result: List[(String, AnyVal)] = List((a,25.5), (a,25.5), (a,49), (b,25.5), (b,25.5), (b,49))

До сих пор я пытался округлить, но результаты не будут равны сумме 100.

scala> val partialResult = seqOfTuples.map (x => (x._1, BigDecimal(x._2).setScale(1, BigDecimal.RoundingMode.HALF_UP).toDouble))
partialResult: List[(String, Double)] = List((a,25.5), (a,25.5), (a,48.9), (b,25.5), (b,25.5), (b,48.9))

Как я могу это сделать?

1 Ответ

0 голосов
/ 13 февраля 2019

Начиная с вашего partialResult (сокращенно pr ниже), вы можете вычесть значения Double из 100.0, пока не достигнете неудобно близкого к нулю значения, после чего вы проигнорируете полученные Double и пересчитаетеего «истинное» значение.

pr.foldLeft((Map.empty[String,Double].withDefaultValue(100.0)
            ,List.empty[(String,Double)])){ case ((m,res),(str,dbl)) =>
    if (math.abs(m(str) - dbl) < 1.1)  //too close
      (m, (str,m(str))::res)           //use remainder
    else
      (m + (str -> (m(str)-dbl)), (str,dbl)::res)  //update Map, build result
}._2.reverse
//res0: List[(String, Double)] = List((a,25.5), (a,25.5), (a,49.0)
//                                  , (b,25.5), (b,25.5), (b,49.0))
...