2011-01-15 16 views
0

Versuchen, einige alte PHP-Code nach Ruby portieren und einige wichtige Informationen zum Erstellen von Arrays in Ruby fehlen.Schleifen und Erstellen eines Arrays in Ruby

Der PHP-Code:

foreach ($results as $r) { 
    $array[$r['column']][] = $r 
} 

Ist dies der einfachste Weg, es in Ruby zu tun? Muss ich das zweite Array initialisieren?

Ich denke, das ist ein einfaches Syntaxproblem, aber mein Googling ist leer geworden. Danke für Ihre Hilfe!

+0

Sind diese Arrays oder Hashes oder Hashes von Arrays? Was ist "Spalte" und was ist das gewünschte Ergebnis? – Phrogz

Antwort

1

Sie indexieren in ein leeres Array, so dass immer nil zurückgegeben wird. Null definiert nicht den Operator < <, so erhalten Sie einen Fehler. Sie müssen den Wert bei Array [Index] initialisieren, wenn Sie den Operator < < verwenden möchten.

Ich gehe davon aus Sie ein Array von Arrays wollen, so können Sie diese stattdessen verwenden, welche den Wert auf Artikel [index] auf ein leeres Array wird initialisiert, wenn es gleich Null ist, bevor der Wert auf sie

items = [] 
array.each do |r| 
    (items[r.column] ||= []) << r 
end 
schieben

Die einzige Änderung hier ist, dass, wenn items [r.column] nil zurückgibt, es gleich einem leeren Array gesetzt wird, sonst wird nichts getan. Wenn Sie den Wert für die Elemente [index] nur auf r setzen möchten, verwenden Sie einfach den Operator =.

+0

Danke Ed! Ich dachte mir, dass es einen kürzeren Weg dafür gibt. – jmccartie

+0

Kein Problem. Es entspricht jedoch nicht Ihrem Beispielcode. Dein Snippet löscht jedes Mal den aktuellen Wert in den Objekten [r.column], während meins nur initialisiert wird, wenn es nichts ist, und dann den Wert anhängt. –

0
array = results.inject([]) { |m, r| m[r.column] = r; m } 

aktualisieren: oh, fügt e1[] = e2 ein neues Array-Element in PHP, so ist tokland Recht, in diesem Fall:

array = results.inject([]) { |m, r| (m[r.column] ||= []) << r; m } 
+0

Ich denke, das OP möchte Werte in einem Array sammeln, nicht nur mit dem letzten überschreiben. – tokland

0

Sind Sie sicher, dass Sie benötigen ein Array als Ausgabe? es scheint, ein Hash wäre bequemer; Darüber hinaus ist es viel einfacher, in Ihrem Szenario zu bauen (das ist in der Regel ein Zeichen in dem richtigen Pfad bist):

# example 
results = [ 
    OpenStruct.new(:x => 1, :cron_column => 0), 
    OpenStruct.new(:x => 2, :cron_column => 1), 
    OpenStruct.new(:x => 3, :cron_column => 1), 
] 

@array = results.group_by(&:cron_column) 
# {0=>[#<OpenStruct x=1, cron_column=0>], 
# 1=>[#<OpenStruct x=2, cron_column=1>, #<OpenStruct x=3, cron_column=1>]} 

Wenn cron_column „hat keine Löcher“ (das ist es, Sie haben Werte von 0 bis N) , können Sie einfach ein Array mit der gleichen Idee erstellen: results.group_by(&:cron_column).sort.map { |k, v| v } oder results.group_by(&:cron_column).sort.map(&:last), wie Sie bevorzugen.

Verwandte Themen