I'm using Ruby 2.4. How do I check if at least 80% of my elements in an array match a certain pattern? I want to see if each element matches the regex
/\d\d?\s*-\s*\d\d?/
I'm using Ruby 2.4. How do I check if at least 80% of my elements in an array match a certain pattern? I want to see if each element matches the regex
/\d\d?\s*-\s*\d\d?/
You can use Enumerable#grep
in conjunction with simple math:
array.grep(/\d\d?\s*-\s*\d\d?/).size / array.size.to_f >= 0.8
To shorten this further you can use Numeric#quo
or Numeric#fdiv
:
array.grep(/\d\d?\s*-\s*\d\d?/).size.quo(array.size) >= 0.8
If performance does matter, you don't need to check all the elements to know if at least 80% of them are maching a condition
With ruby 2.3 this implementation is a bit faster than the count solution and twice faster than the grep solution :
def pareto_match(array, proportion: 0.8)
min_success= (array.count * proportion).round(4)
max_failures= (array.count * (1 - proportion)).round(4)
success= 0
failure= 0
array.each do |element|
if yield(element)
success+= 1
return true if success >= min_success
else
failure+= 1
return false if failure > max_failures
end
end
end
pareto_match(array){|e| e =~ /\d\d?\s*-\s*\d\d?/}
I would write:
(array.count{|item| item =~ /\d\d?\s*-\s*\d\d?/} / array.size) >= 0.8