невозможно преобразовать массив в целое число - PullRequest
0 голосов
/ 23 июля 2010

Я пытаюсь перебрать массив @chem_species = ["H2", "S", "O4"] и умножить на постоянное число умноженных на количество присутствующих констант: H = 1.01 * 2, S = 32.1 * 1 и так далее Конечно, константы определены внутри класса перед методом экземпляра.

Код, который я создал для этого, не работает:

def fw
x = @chem_species.map { |chem| chem.scan(/[A-Z]/)}
y = @chem_species.map { |chem| chem.scan({/\d+/)}
@mm = x[0] * y[0] 
end

урожайность -> TypeError: can't convert Array into Integer

Любые предложения о том, как лучше это кодировать? Спасибо за ваше понимание заранее.

Ответы [ 5 ]

3 голосов
/ 23 июля 2010

Как насчет того, чтобы сделать все это за одно сканирование и карту?Метод String#scan всегда возвращает массив строк, которым он соответствует.Посмотрите на это:

irb> "H2".scan /[A-Z]+|\d+/i
  => ["H", "2"]

Так что просто примените это ко всем вашим @chem_species, используя map:

irb> @chem_species.map! { |chem| chem.scan /[A-Z]+|\d+/i }
  => [["H", "2"], ["S"], ["O", "4"]]

ОК, теперь сопоставьте с @chem_species, преобразовав каждый элементсимвол к значению его константы, а каждый коэффициент к целому числу:

irb> H = 1.01
irb> S = 32.01
irb> O = 15.99
irb> @chem_species.map { |(elem, coeff)| self.class.const_get(elem) * (coeff || 1).to_i }
  => [2.02, 32.01, 63.96]

Там ваши молярные массы!

Кстати, я предлагаю вам посмотреть молярные массы в одномхеш-константа вместо нескольких констант для каждого элемента.Вот так:

MASSES = { :H => 1.01, :S => 32.01, :O => 15.99 }

Тогда последняя карта будет выглядеть так:

@chem_species.map { |(elem, coeff)| MASSES[elem.to_sym] * (coeff || 1).to_i }
0 голосов
/ 23 июля 2010

(однострочное оповещение, не по теме)

Вы можете разобрать формулу напрямую:

"H2SO4".scan(/([A-Z][a-z]*)(\d*)/)
# -> [["H", "2"], ["S", ""], ["O", "4"]]

Рассчитать частичные суммы:

aw = { 'H' => 1.01, 'S' => 32.07, 'O' => 16.00 }
"H2SO4".scan(/([A-Z][a-z]*)(\d*)/).collect{|e,x| aw[e] * (x==""?1:x).to_i}
# -> [2.02, 32.07, 64.0]

общая сумма:

"H2SO4".scan(/([A-Z][a-z]*)(\d*)/).collect{|e,x| aw[e] * (x==""?1:x).to_i}.inject{|s,x| s+x}
# -> 98.09
0 голосов
/ 23 июля 2010

Вы смотрели на вывод @chem_species.map { |chem| chem.scan(/[A-Z]/)} (или второй в этом отношении)? Он дает вам массив массивов, поэтому, если вы действительно хотите придерживаться этого подхода, вам придется сделать x[0][0].

Вместо map ping сделайте each

@chem_species.each { |c| c.scan(/[A-Z]/) }

Редактировать: только что понял, что это не сработало, как я думал, мои извинения за глупый ответ: P

0 голосов
/ 23 июля 2010

Вот способ умножить значения, как только они у вас есть. Оператор * не будет работать с массивами.

x = [ 4, 5, 6 ]
y = [ 7, 8, 9 ]
res = []
x.zip(y) { |a,b| res.push(a*b) }
res.inject(0) { |sum, v| sum += v}
# sum => 122

Или, вырезая среднего человека:

x = [ 4, 5, 6 ]
y = [ 7, 8, 9 ]
res = 0
x.zip(y) { |a,b| res += (a*b) }
# res => 122
0 голосов
/ 23 июля 2010

В вашем коде есть синтаксическая ошибка: возможно, это должно быть:

def fw
x = @chem_species.map { |chem| chem.scan(/[A-Z]/)}
y = @chem_species.map { |chem| chem.scan(/\d+/)}
@mm = x[0] * y[0] 
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...