2009-05-14 3 views
3

У меня проблема, которую я не могу решить для меня. Я пишу приложение Ruby (я был разработчиком PHP уже 8 лет, начиная с Ruby), который продает билеты в концертном зале. Каждое место имеет ряд (a ... z) и число (1 ... x). Модель базы данных имеет строку (string) и num (int) для каждого места.Ruby - Символы карты целым числам в массиве 2d

Как я могу преобразовать массив сидений из базы данных в массив 2d? Например, сиденье A1 будет входить в место [1] [1] = «значение»; сиденье C4 будет отображаться на сиденье [3] [4] = значение. Проблема заключается в преобразовании строки строки в Ascii и вычитании смещения? Или есть более простой способ?

Большое спасибо

+0

Зачем преобразовывать строку в целое число? Вместо этого вы можете просто ввести строку. –

+0

Спасибо Мэтт. Не уверен, что я тебя понимаю? Если я попытаюсь сделать сидения [seat.row] [seat.num] = значение, я получаю TypeError, не могу преобразовать String в Integer. Поэтому я предполагал, что массивы были проиндексированы только целым числом, поэтому преобразование было необходимо? –

+0

@Dan: Ruby имеет хэши, которые почти такие же, как ассоциативные массивы PHP. Они индексируются так же, как массивы (см. Мой ответ), но пустой хэш представлен как {} вместо []. – Pesto

ответ

4

Самый простой способ, вероятно, использовать хэш вместо этого. Например: seat['A'][1] = value

Но если вам действительно нужен массив по какой-то причине, то описанный вами метод является самым простым. Предполагая, что строка строки является одним символом «от» до «Z», вы можете сделать это, используя row_string[0] - ?A (или row_string[0] - ?A + 1, если вы хотите, чтобы индекс начинался с 1, как в вашем примере). Для версии с несколькими символьной строкой, где АА после ряда Z, вы можете сделать это в 1.8.7 и новее:

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

Вы можете UPCASE вашей строки строки заранее, просто чтобы быть на безопасной стороне.

В 1.8.6 и ниже String не имеет метода bytes. Вы можете сделать то же самое, выполнив:

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

Согласен, хэш - лучший способ справиться с этим. –

+0

Большое спасибо. Хеши, безусловно, самый простой путь вперед. Однако: выходов = {} для сиденья в self.seats \t выходов [seat.num] [seat.row] = "да" концевых обратных выходов производит ошибку при оценке ноля [] =. , И seat.row, и seat.num утверждают значения, поэтому я предполагаю, что это должна быть синтаксическая ошибка. Спасибо за вашу помощь. –

+0

Это не синтаксическая ошибка, вам просто нужно создать массив для каждой строки, прежде чем пытаться присвоить ему элементы. Попробуйте это: outs = {}; для сиденья в самолете; out [seat.num] || = []; аут [сиденье.нум] [seat.row] = «да»; end. Строка «outs [seat.num] || = []» устанавливает аут [seat.num] как пустой массив, если он еще не имеет значения. Кроме того, вам может быть лучше использовать true вместо «yes». – Pesto

1

Ну, чтобы получить индекс письма вы могли бы сделать что-то вроде этого

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

, который будет возвращать 2

Я замечаю в массиве примеры, которые вы дали вам, начали A = 1 вместо 0.

2

Хорошо, решение, которое я придумал, похоже, делает трюк:

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 

Огромное спасибо всем за такие быстрые и полезные ответы. Я обязательно помогу другим с PHP!

Смежные вопросы