Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I select from a given set of values, rounding up?

I've got a ruby array of hashes with two keys, 'tier' and 'price'. For a given price, I want to return the tier.

This is simple enough with exact matching, but how do I ensure I always have a match by rounding my input value up to the next value in the array?

For example, given the array below, if I have a value of '499', I want to return '10'.

tiers = [
    { tier: 0, price: 0 },
    { tier: 1, price: 50 },
    { tier: 2, price: 100 },
    { tier: 3, price: 150 },
    { tier: 4, price: 200 },
    { tier: 5, price: 250 },
    { tier: 6, price: 300 },
    { tier: 7, price: 350 },
    { tier: 8, price: 400 },
    { tier: 9, price: 450 },
    { tier: 10, price: 500 },
    { tier: 11, price: 550 },
    { tier: 12, price: 600 },
    { tier: 13, price: 650 },
    { tier: 14, price: 700 },
    { tier: 15, price: 750 },
    { tier: 16, price: 800 },
    { tier: 17, price: 850 },
    { tier: 18, price: 880 },
    { tier: 19, price: 950 },
    { tier: 20, price: 1000 }
]

I can get an exact match with tiers.detect { |tier| tier[:price] == "500"}[:tier], but this will return an error if I don't have a match. I could increment my input value until I return a match but that seems very inefficient.

I considered rounding my input value, but you'll notice that the increment isn't always the same (from tier 17 to 18 the price only increases by 30).

like image 424
Nick Barreto Avatar asked Mar 08 '23 07:03

Nick Barreto


1 Answers

You could enumerate all tiers in pairs and evaluate your price against the pair. Something like this:

def detect_tier(price)
  tiers.each_cons(2) do |t1, t2|
    next if price < t1[:price] # too low
    next if price > t2[:price] # too high

    return t1[:tier] if price == t1[:price] # matches tier price exactly
    return t2[:tier] # "round up"
  end
end

detect_tier(10) # => 1
detect_tier(100) # => 2
detect_tier(499) # => 10
like image 183
Sergio Tulentsev Avatar answered Mar 15 '23 22:03

Sergio Tulentsev