如何从数组的一部分中找出不同的元素?

时间:2017-01-10 02:37:52

标签: arrays ruby unique distinct

我正在使用Ruby 2.4。我有一个像这样的值的数组

['1/ 8', '5 / 16', nil, '12 / 25', nil, '8/9']

我的问题是,当数组中的元素不是nil时,如何找出"/"之后的所有唯一值?您可以假设数组中的所有值都是nil"/"后跟一定程度的空格,然后是数字。

5 个答案:

答案 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']的唯一分母,根据您的需要,可能是某个功能或错误。