#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))