SORU
16 AĞUSTOS 2011, Salı


En iyi iki harita birleştirme ve aynı anahtar değerleri toplamı?

val map1 = Map(1 -> 9 , 2 -> 20)
val map2 = Map(1 -> 100, 3 -> 300)

Bunları birleştirmek, ve aynı anahtar değerleri toplamak istiyorum. Sonuç olacak:

Map(2->20, 1->109, 3->300)

Şimdi 2 çözüm var:

val list = map1.toList    map2.toList
val merged = list.groupBy ( _._1) .map { case (k,v) => k -> v.map(_._2).sum }

ve

val merged = (map1 /: map2) { case (map, (k,v)) =>
    map   ( k -> (v   map.getOrElse(k, 0)) )
}

Ama eğer daha iyi bir çözüm olup olmadığını bilmek istiyorum.

CEVAP
16 AĞUSTOS 2011, Salı


Scalaz burada ne yapmak istediğini yakalar, ve muhtemelen en kısa/en temiz çözüm yol Semigroup bir kavram vardır

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> val map1 = Map(1 -> 9 , 2 -> 20)
map1: scala.collection.immutable.Map[Int,Int] = Map(1 -> 9, 2 -> 20)

scala> val map2 = Map(1 -> 100, 3 -> 300)
map2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 100, 3 -> 300)

scala> map1 | | map2
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 109, 3 -> 300, 2 -> 20)

Özellikle, Map[K, V] ikili operatör haritalar, V'herhangi bir yinelenen değerler üzerinden. s semigroup operatörü katlama tuşları birleştirir Int standart semigroup toplama operatörü kullanır, her yinelenen anahtar değerleri toplamı olsun.

Edit: User482745 isteği doğrultusunda biraz daha ayrıntı.

Matematiksel olarak semigroup sadece değerler, birlikte kümesinden iki değer alır ve bu dizi başka bir değer üreten bir operatör. Ayrıca altında tamsayılar bir semigroup, örneğin - operatör başka bir int yapmak için iki değer vermez birleştirir.

Ayrıca define bir semigroup üzerinde kurulan "tüm haritaları ile verilen bir anahtar yazın ve değer türü", sürece kadar gelebilir bazı operasyon birleştiren iki harita üretmek için yeni bir tane olan bir şekilde ikisinin birleşimi girdi.

Eğer iki harita görünen anahtarları ise orada hayır, bu önemsiz. Eğer aynı anahtar hem haritalar varsa, anahtar Haritalar için bu iki değeri birleştirmek için ihtiyacımız var. Hmm, biz sadece aynı türden iki tarafı bir araya getiren bir operatör tarif değil mi? Bu yüzden içinde Scalaz bir semigroup Map[K, V] varsa ve yalnızca bir Semigroup V var V'In semigroup için kullanılır birleştirmek değerleri iki harita olan atanır aynı anahtar.

Çünkü Int değeri yazın burada, "çarpışma" 1 anahtar çözülmüş olarak tamsayı ayrıca iki eşlenen değerleri (o ne İnt. semigroup operatör yok), dolayısıyla 100 9. Eğer değerleri Dizeleri olsaydı, bir çarpışma iki eşlenen değerleri (bu Dize için semigroup operatör yapıyor çünkü tekrar) dize birleştirme sonuçlanırdı.

(Ve dize birleştirme değişmeli, "a" "b" != "b" "a" - çünkü ilginçtir, ortaya çıkan semigroup operasyon değil. map1 | | map2 İnt durum, String durumda map2 | | map1, ama farklı değildir.)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • androidandme

    androidandme

    10 Mart 2009
  • BruBearBaby

    BruBearBaby

    25 Ocak 2011
  • Kap Slap

    Kap Slap

    8 Mart 2010