我正在使用Ruby 2.4。我有一个像这样的值的数组
['1/ 8', '5 / 16', nil, '12 / 25', nil, '8/9']
我的问题是,当数组中的元素不是nil
时,如何找出"/"
之后的所有唯一值?您可以假设数组中的所有值都是nil
或"/"
后跟一定程度的空格,然后是数字。
答案 0 :(得分:0)
如果我的问题正确无误,您需要从8
获取'8'
(或'1/ 8'
?):
a = ['1/ 8', '5 / 16', nil, '12 / 25', nil, '8/9']
a.compact.each_with_object({}) do |str, hash|
hash[str] = str.split('/').last.split(' ').map(&:to_i).uniq
end
#=> {"1/ 8"=>[8], "5 / 16"=>[16], "12 / 25"=>[25], "8/9"=>[9]}
如果您只需要获取uniq值:
values = a.compact.flat_map {|str| str.split('/').last.split(' ').map(&:to_i) }.uniq
#=> [8, 16, 25, 9]
答案 1 :(得分:0)
使用Eli的建议使用理性类型:
a.compact.map{|f| f.delete(' ').to_r}.map(&:denominator).uniq
编辑:请注意,这是基于这些是分数的假设(因此适用to_r
)。
答案 2 :(得分:0)
试试这个
arr.map { |str| str && str[%r{/(.*)}, 1].to_i }
# => [8, 16, nil, 25, nil, 9]
这是如何运作的?
map
是一个将结果收集到新数组中的循环str && ...
不是,则str
执行后一部分
str[regexp, 1]
匹配正则表达式并返回第一个捕获组%r{/(.*)}
是一个正则表达式,匹配斜杠后的所有内容答案 3 :(得分:0)
我从字面上解释了这个问题。
arr = ['1/ 8', 'dog/ 25', nil, '12 / 25', nil, '8/9', '1/2 5', '1 / cat', '2/', '3 4']
arr.map { |obj| obj.to_s[/(?<=\/).*/] }.compact.uniq
#=> [" 8", " 25", "9", "2 5", " cat", ""]
正则表达式匹配正斜杠后面的所有字符,正向斜线与正向后观匹配。
注意nil.to_s #=> ''
。
答案 4 :(得分:0)
您似乎正在使用Rational,因此您可以使用Rational
:
array = ['1/ 8', '5 / 16', nil, '12 / 25', nil, '8/9']
rationals = array.compact.map do |string|
Rational(string.delete(' '))
end
#=> [(1/8), (5/16), (12/25), (8/9)]
unique_denominators = rationals.map(&:denominator).uniq
#=> [8, 16, 25, 9]
请注意,Rational是不可简化的:
您将[3]
作为['4/ 6', '1 / 3']
的唯一分母,根据您的需要,可能是某个功能或错误。