# Get a hash that matches minimum quantity

I have an array of hashes:

``````arr_of_hsh =[
{minimum_quantity: "250", cost: "1.5600"},
{minimum_quantity: "500", cost: "1.3500"},
{minimum_quantity: "1000", cost: "1.1800"},
{minimum_quantity: "2500", cost: "1.0200"}
]
``````

Given a certain amount, I'd like to get the hash whose value for `:minimum_quantity` is the closest to the amount among those less than or equal to the amount. For example, if the amount was 300, this hash would be returned:

``````{minimum_quantity: "250", cost: "1.5600"}
``````

and if the amount was 1000:

``````{minimum_quantity: "1000", cost: "1.1800"}
``````

## 2 Answers Get a hash that matches minimum quantity

Keeping your data structure the same I'd say this way

`````` arr_of_hsh.select { |item| item[:minimum_quantity].to_i <= quantity }.
max_by { |item| item[:minimum_quantity].to_i }
``````

### Ursus3 months ago

Here is a single-pass solution.

``````def f(arr, qty)
h = arr.min_by do |h|
n = h[:minimum_quantity].to_i
n <= qty ? (qty-n) : Float::INFINITY
end
h[:minimum_quantity].to_i <= qty ? h : nil
end

(100..1100).step(100).each { |qty| puts "#{qty}: #{f(arr_of_hsh, qty)}" }
100: nil
200: nil
300: {:minimum_quantity=>"250",  :cost=>"1.5600"}
400: {:minimum_quantity=>"250",  :cost=>"1.5600"}
500: {:minimum_quantity=>"500",  :cost=>"1.3500"}
600: {:minimum_quantity=>"500",  :cost=>"1.3500"}
700: {:minimum_quantity=>"500",  :cost=>"1.3500"}
800: {:minimum_quantity=>"500",  :cost=>"1.3500"}
900: {:minimum_quantity=>"500",  :cost=>"1.3500"}
1000: {:minimum_quantity=>"1000", :cost=>"1.1800"}
1100: {:minimum_quantity=>"1000", :cost=>"1.1800"}
``````

If the method is to be called several times for a given `arr_of_hsh`, sort `arr_of_hsh` by decreasing value of `arr_by_hsh[:minimum_quantity.to_i` and then simply use Enumerable#find.

``````def f(arr, qty)
h = arr.find { |h| h[:minimum_quantity].to_i <= qty }
end

arr = arr_of_hsh.sort_by { |h| -h[:minimum_quantity].to_i }
#=> [{:minimum_quantity=>"2500", :cost=>"1.0200"},
#    {:minimum_quantity=>"1000", :cost=>"1.1800"},
#    {:minimum_quantity=>"500", :cost=>"1.3500"},
#    {:minimum_quantity=>"250", :cost=>"1.5600"}]
(100..1100).step(100).each { |qty| puts "#{qty}: #{f(arr, qty)}" }
#=> (same as above)
``````