2012-06-13 3 views
5

Ich bin so in Ruby Sprache, wenn ich nach Wert einen Hash zu sortieren versuche ich diese Methode zu sortieren verwendet:was der Mittelwert * ist und flach in Ruby

movie_popularity.sort_by{|m,p| p}.reverse 

aber die die Methode sort gibt ein Array, während ich ein Hash werden zurückgeführt, so habe ich diesen Befehl müssen:

movie_popularity=Hash[*movie_popularity.sort_by{|m,p| p}.reverse.flatten] 

meine Frage ist, was ist die Bedeutung von * und flatten in der obigen Zeile?

Dank =)

Antwort

10

Die * heißt der "Splat-Operator"; Ich bin mir nicht sicher, ob ich Ihnen die technische Definition geben könnte (obwohl ich sicher bin, dass Sie es bald genug mit Googles Hilfe finden würden), aber die Art und Weise, wie ich es beschreiben würde, ist, dass es im Grunde genommen den Platz des Handschreibens einnimmt Komma-getrennte Werte im Code.

Um dies konkreter zu machen, betrachten Sie den Fall Hash[], den Sie in Ihrem Beispiel verwendet haben. Die Hash Klasse hat eine [] Klassenmethode, die eine variable Anzahl von Argumenten nimmt und in der Regel kann wie folgt aufgerufen werden:

# Returns { "foo" => 1, "bar" => 2 } 
h = Hash["foo", 1, "bar", 2] 

Beachten Sie, dass kein Array oder ein Hash oder alles, was ich übergeben; es ist eine (handgeschriebene) Sequenz von Werten. Mit dem Operator * können Sie im Grunde dasselbe erreichen, wenn Sie ein Array verwenden - in Ihrem Fall das, das von movie_popularity.sort_by{|m,p| p}.reverse.flatten zurückgegeben wird.

Wie für diesen flatten Anruf: Wenn Sie sort_by auf einem Hash nennen, sind Sie wirklich nutzen das Enumerable-Modul, das in einer Vielzahl von Klassen enthalten ist (vor allem Array und Hash), die Aufzählung liefern. Im Falle eines Hash, haben Sie wahrscheinlich bemerkt, dass statt wie diese über ein Iterieren:

hash.each { |value| ... } 

Stattdessen Sie dies tun:

hash.each { |key, value| ... } 

Das heißt, Iterieren über eine Hash-Ausbeuten zwei Werte bei jeder Iteration. So würde Ihr sort_by Aufruf allein eine Sequenz von Paaren zurückgeben. Durch Aufruf von flatten auf dieses Ergebnis werden die Paare in eine eindimensionale Folge von Werten wie folgt zerlegt:

# Returns [1, 2, 3, 4] 
[[1, 2], [3, 4]].flatten