我正在尝试遍历数组@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
有关如何更好地编码的任何建议?感谢您提前了解。
答案 0 :(得分:3)
如何在一次扫描中完成所有操作&地图? 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 }
答案 1 :(得分: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
答案 2 :(得分:0)
您是否看过@chem_species.map { |chem| chem.scan(/[A-Z]/)}
(或者第二个)的输出?它给你一系列数组,所以如果你真的想坚持这种方法,你必须做x[0][0]
。
<击>
而不是map
ping,执行each
@chem_species.each { |c| c.scan(/[A-Z]/) }
击> <击> 撞击>
编辑:刚才意识到这根本无法解决我的想法,我对一个愚蠢的回答道歉:P
答案 3 :(得分: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
答案 4 :(得分: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