2010-02-06 13 views
11

Bardzo przydatny kod Ruby:Scala odpowiednik mapy Ruby?

some_map.each do |key,value| 
    # do something with key or value 
end 

Scala równoważne:

someMap.foreach(entry => { 
    val (key,value) = entry 
    // do something with key or value 
}) 

konieczności dodawania dodatkowym val Bugs linia mnie. Nie mogłem wymyślić, jak podać funkcję arg, aby wyodrębnić krotkę, więc zastanawiam się, czy istnieje sposób, aby to zrobić, lub dlaczego nie ma foreach, która wydobywa klucz i wartość dla mnie?

Odpowiedz

19

To działa też:

someMap.foreach {case (key, value) => 
    // do something with key and/or value 
} 
+0

Oświadczenie sprawy jest tak naprawdę częściową funkcją w przebraniu, dlatego ten przydatny skrót dekompozycji działa. To może pomóc komuś, kto jest mistyfikowany przez błąd typu wynikający z niedopasowania tego rodzaju ekspresji. –

+0

Dobry artykuł o częściowych funkcjach tutaj http://ebruchez.blogspot.com/2011/10/scala-partial-functions-without-phd.html – foolshat

11

mi się podoba:

scala> val foo = Map(1 -> "goo", 2 -> "boo") 
foo: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> goo, 2 -> boo) 

scala> for ((k,v) <- foo) println(k + " " + v) 
1 goo 
2 boo 
+0

Nie ma potrzeby używania 'val' wewnątrz generatora' for'. –

5

Nie trzeba nawet val w pętli for:

Idąc za przykładem ViktorKlang za:

scala> val foo = Map(1 -> "goo", 2 -> "boo") 
foo: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> goo, 2 -> boo) 

scala> for ((k, v) <- foo) println(k + " " + v) 
1 goo 
2 boo 

Zauważ, że for jest raczej mocny w Scala, dzięki czemu można z niego korzystać także za sequence comprehensions:

scala> val bar = for (val (k, v) <- foo) yield k 
bar: Iterable[Int] = ArrayBuffer(1, 2) 
+0

'for' to w rzeczywistości Monad Comprehension pod postacią pętli' for', aby nie odstraszać programistów Javy takimi pojęciami jak * Monad *. (Podobnie jak w przypadku zapytań w języku C#/VB.NET są to po prostu monadyczne interpretacje ukryte pod nazwą zapytań SQL). A więc jest to nawet potężniejsze niż rozumienie sekwencji. –

+1

Jörg, nie używaj słowa M, przeraża ludzi ;-) –

+0

@ViktorKlang: Dokładnie! Dlatego Martin Odersky ukrył je jako coś, co już znają programiści Javy: pętlę 'for'. I Erik Meijer ukrył je jako zapytanie SQL w C# i VB.NET, Don Syme ukrył je jako powłokę powłoki Uniksa w F #, Simon Peyton Jones przebrał je jako blok C w Haskell. (Czasami myślę, że byliby * mniej * przerażający, gdyby nie ukrywali się ciągle w cieniu ...) –

2

Function.tupled przekształca funkcję (a1, a2) => b) do funkcji ((a1, a2)) => b.

import Function._ 
someMap foreach tupled((key, value) => printf("%s ==> %s\n", key, value))