我有一个数组,我正在循环并将特定值推送到一个单独的数组。前任:
first_array = ["Promoter: 8", "Passive: 7"]
我想将每个整数值推送到一个单独的数组中,最后看起来像这样:
final_array = [8,7]
新数组中的值最好是整数。我想不出一种将字符串中的所有数值推送到新数组的方法,但是做我想要的最好的选择是什么?
first_array.map{|s| s[/\d+/].to_i}
# => [8, 7]
first_array.map{|a| a.match(/\d+/)}.compact.map{|a| a[0].to_i }
而且我必须添加这个超短但复杂的单线解决方案:
a = ["Promoter: 8", "Passive: 7"]
p a.grep(/(\d+)/){$&.to_i} #=> [8,7]
按照公式,您的问题有一个简单实用的答案,其他人已经提供了。但在我看来,你的字符串数组
a = ["Promoter: 8", "Passive: 7"]
羡慕成为一个Hash
。因此,从更广泛的角度来看,我会先自由地将其转换为 Hash:
require 'pyper' # (type "gem install pyper" in your command line to install it)
hsh = Hash[ a.τBmm2dτ &/(\w+): *(\d+)/.method( :match ) ]
#=> {"Promoter"=>"8", "Passive"=>"7"}
# (The construction of #τBmm2dτ Pyper method will be explained in the appendix.)
现在,将您的输入数据放在哈希中,您可以更轻松地处理它们,例如。
hsh.τmbtiτ
#=> [8, 7]
附录: Pyper 方法的解释。
Pyper 方法与 Lisp #car/#cdr 方法相似之处在于,字母组合控制方法行为。在第一种方法中,#τBmm2dτ
:
因此,在 中#τBmm2dτ
,Bm
按如下方式应用块:
x = ["Promoter: 8", "Passive: 7"].map &/(\w+): *(\d+)/.method( :match )
#=> [#<MatchData "Promoter: 8" 1:"Promoter" 2:"8">, #<MatchData "Passive: 7" 1:"Passive" 2:"7">]
# Which results in an array of 2 MatchData objects.
然后, chars 使用和charsm2d
映射 ( m
) MatchData 对象。性格给2
d
2
x = x.map { |e| e.to_a.take 3 }
#=> [["Promoter: 8", "Promoter", "8"], ["Passive: 7", "Passive", "7"]]
并d
从每个元素中删除第一个元素:
x = x.map { |e| e.drop 1 }
#=> [["Promoter", "8"], ["Passive", "7"]]
在第二个方法中,#τmbtiτ
,m
表示再次#map
,b
表示取第二个元素,并ti
表示将其转换为Integer
:
{"Promoter"=>"8", "Passive"=>"7"}.to_a.map { |e| Integer e[1] }
#=> [8, 7]
如果每个字符串的整数部分(看起来像散列的成员)总是以至少一个空格开头,并且没有其他空格(可能在字符串的开头除外),您可以这样做:
first_array = ["Promoter: 8", "Passive: 7"]
Hash[*first_array.map(&:split).flatten].values.map(&:to_i) # => [8,7]
注意 splat 的必要性:
Hash[*["Promoter:", "8", "Passive:", "7"]]
=> Hash["Promoter:", "8", "Passive:", "7"]
=> {"Promoter:" => "8", "Passive:" => "7"}