Преобразования последовательности в scala

#scala #functional-programming

#scala #функциональное программирование

Вопрос:

В scala есть простой способ преобразования этой последовательности

Seq(("a", 1), ("b", 2), ("a", 3), ("c", 4), ("b", 5))

в это Seq(("a", 4), ("b", 7), ("c", 4)) ?

Спасибо

Ответ №1:

Я не уверен, имели ли вы в виду String s во второй ординате кортежа. Предполагая Seq[(String, Int)] , вы можете использовать groupBy для группировки элементов по первой ординате:

 Seq(("a", 1), ("b", 2), ("a", 3), ("c", 4), ("b", 5))
   .groupBy(_._1)
   .mapValues(_.map(_._2).sum)
   .toSeq
  

В противном случае вы будете следующим дополнительным .toInt

Комментарии:

1. Это был тупо. Я отредактировал свой вопрос. Спасибо за быстрый ответ!

2. Стоит отметить, что это не будет поддерживать порядок.

3. groupBy нарушит порядок, да.

4. аналогичное решение: s.groupBy(_._1).map{case (k,v)=> (k,v.map{case(s,i) => i}.сумма)}.toSeq

Ответ №2:

Вот другой способ, путем распаковки и использования второго элемента в кортеже.

 val sq = sqSeq(("a", 1), ("b", 2), ("a", 3), ("c", 4), ("b", 5))
sq.groupBy(_._1)
  .transform {(k,lt) => lt.unzip._2.sum}
  .toSeq
  

Приведенные выше детали кода:

 scala> sq.groupBy(_._1)
res01: scala.collection.immutable.Map[String,Seq[(String, Int)]] = Map(b -> List((b,2), (b,5)), a -> List((a,1), (a,3)), c -> List((c,4)))

scala> sq.groupBy(_._1).transform {(k,lt) => lt.unzip._2.sum}
res02: scala.collection.immutable.Map[String,Int] = Map(b -> 7, a -> 4, c -> 4)


scala> sq.groupBy(_._1).transform {(k,lt) => lt.unzip._2.sum}.toSeq
res03: Seq[(String, Int)] = ArrayBuffer((b,7), (a,4), (c,4))