0

我试图遍历一个数组,@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

关于如何更好地编码的任何建议?提前感谢您的洞察力。

4

5 回答 5

3

在一次扫描和地图中完成所有操作怎么样?该String#scan方法总是返回它匹配的字符串数组。看这个:

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

因此,只需将其应用于您的所有@chem_speciesusing map

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

好的,现在 map over @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 }
于 2010-07-23T00:17:15.153 回答
0

(单行警报,离题警报)

您可以直接解析公式:

"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
于 2010-07-23T00:30:42.050 回答
0

您的代码中有语法错误:也许应该是:

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
于 2010-07-23T00:02:58.623 回答
0

您是否查看过@chem_species.map { |chem| chem.scan(/[A-Z]/)}(或第二个)的输出?它给了你一个数组数组,所以如果你真的想坚持这种方法,你必须做x[0][0].

而不是mapping,做each

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

编辑:刚刚意识到这根本不起作用,我对一个愚蠢的回答表示歉意:P

于 2010-07-23T00:04:29.947 回答
0

这是一种将值相乘的方法。* 运算符不适用于数组。

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
于 2010-07-23T00:13:32.637 回答