2009-05-14 20 views
3

Ich habe ein Problem, das ich nicht für das Leben von mir lösen kann. Ich schreibe eine Ruby-App (ich bin seit 8 Jahren ein PHP-Entwickler, angefangen bei Ruby), der Tickets für einen Konzertsaal verkauft. Jeder Sitz hat eine Reihe (a ... z) und eine Nummer (1 ... x). Das Datenbankmodell hat für jeden Platz eine Zeile (Zeichenfolge) und eine Nummer (Int).Ruby - Zeichen auf Ganzzahlen in 2d Array

Wie kann ich mein Array von Sitzen von der Datenbank in ein 2D-Array konvertieren? Zum Beispiel würde der Sitz A1 in den Sitz gehen [1] [1] = "Wert"; Sitz C4 würde auf Platz [3] [4] = Wert abbilden. Das Problem besteht darin, die Zeilenfolge in Ascii zu konvertieren und den Offset zu subtrahieren. Oder gibt es einen leichteren Weg?

Vielen Dank

+0

Warum die Zeile in eine Ganzzahl konvertieren? Sie können stattdessen die Zeichenfolge dort einfügen. –

+0

Danke Matt. Nicht sicher, dass ich dich kriege? Wenn ich versuche und mache Sitze [Sitzplatz.row] [Sitzplatz.Num] = Wert bekomme ich einen TypeError kann nicht String in Integer konvertieren. Daher nahm ich an, dass Arrays nur durch ganze Zahlen indiziert wurden, also war eine Konvertierung notwendig? –

+0

@Dan: Ruby hat Hashes, die den assoziativen Arrays von PHP sehr ähnlich sind. Sie werden wie Arrays indiziert (siehe meine Antwort), aber ein leerer Hash wird als {} anstelle von [] dargestellt. – Pesto

Antwort

4

Der einfachste Weg ist wahrscheinlich stattdessen einen Hash zu verwenden. Zum Beispiel: seat['A'][1] = value

Aber wenn Sie wirklich ein Array aus irgendeinem Grund benötigen, dann ist die Methode, die Sie beschreiben, die einfachste. Angenommen, der Zeilenstring ist ein einzelnes Zeichen 'A' bis 'Z', können Sie dies tun mit row_string[0] - ?A (oder row_string[0] - ?A + 1, wenn Sie den Index beginnend bei 1 wie in Ihrem Beispiel wollen). Für eine Mehrzeichen Version, in der Reihe AA nach Reihe Z ist, können Sie dies in 1.8.7 und neuer:

row_num = row_string.bytes.inject(0) {|total, x| total = total * 26 + x - ?A + 1} 

Vielleicht möchten Sie Ihre Zeile Zeichenfolge vorher upcase, nur um auf der sicheren Seite zu sein.

In 1.8.6 und darunter hat String keine bytes Methode. Sie können das Gleiche erreichen, indem Sie:

row_num = 0 
row_string.each_byte {|x| row_num = row_num * 26 + x - ?A + 1} 
+0

Ich stimme zu, ein Hash ist der beste Weg, damit umzugehen. –

+0

Vielen Dank in der Tat. Hashes sind sicherlich der einfachste Weg nach vorne. Allerdings: outs = {} für Sitz in self.seats \t outs [seat.num] [seat.row] = "yes" Ende return outs Der Fehler produziert trat bei Null Auswertung [] =. . Sowohl seat.row als auch seat.num haben Werte angegeben, daher vermute ich, dass es sich um einen Syntaxfehler handeln muss. Vielen Dank für Ihre Hilfe. –

+0

Es ist kein Syntaxfehler, Sie müssen nur das Array für jede Zeile erstellen, bevor Sie Elemente zuweisen. Versuchen Sie Folgendes: outs = {}; für Sitz in Selbstsitzen; outs [Sitz.num] || = []; outs [Sitzplatznummer] [Sitzplatzplatz] = "ja"; end Die Zeile "outs [seat.num] || = []" setzt out [seat.num] als leeres Array, wenn es noch keinen Wert hat. Sie könnten auch besser mit True anstelle von "Ja". – Pesto

1

Nun den Index eines Briefes erhalten Sie so etwas wie dieses

('A'..'Z').to_a.index('C') 

tun könnte, die 2

zurückkehren würde ich im Array bemerken Beispiele, die Sie gaben, begann A = 1 anstelle von 0.

2

Ok, die Lösung, die ich mir ausgedacht habe, scheint den Trick zu tun:

seat_array = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) } 
for seat in self.seats 
seat_array[seat.row.downcase][seat.num] = seat 
end 
return seat_array 

Vielen Dank an alle für so schnelle und nützliche Antworten. Ich werde sicherlich anderen mit PHP helfen!