Chiara Ani
Chiara Ani

Reputation: 1083

How to know if a number is greater or smaller than a range?

(1..2) <=> 3 # => -1
(-2..21) <=> -10 # => 1
(-2..21) <=> 0 # => 0

Is there a ruby implemented method already for this function? Otherwise, I would code it myself.

Upvotes: 3

Views: 545

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110675

def where_is_val?(range, val)
  case val
  when range
    0
  when ..range.begin
    -1
  else
    1
  end
end
where_is_val?(0..10,  -1)  #=> -1
where_is_val?(0..10,   0)  #=>  0
where_is_val?(0..10,   5)  #=>  0
where_is_val?(0..10,  10)  #=>  0
where_is_val?(0..10,  15)  #=>  1
where_is_val?(0...10, 10)  #=>  1
where_is_val?('c'..'m',  'a')  #=> -1
where_is_val?('c'..'m',  'c')  #=>  0
where_is_val?('c'..'m',  'f')  #=>  0
where_is_val?('c'..'m',  'm')  #=>  0
where_is_val?('c'..'m',  'z')  #=>  1
where_is_val?('c'...'m', 'm')  #=>  1

Notice that this works with both inclusive (0..10) and exclusive (0...10) ranges.

Upvotes: 2

Stefan
Stefan

Reputation: 114178

You can utilize clamp:

  3.clamp( 1..2 ) <=>   3  # => -1
-10.clamp(-2..21) <=> -10  # =>  1
  0.clamp(-2..21) <=>   0  # =>  0

in general:

number.clamp(range) <=> number

To get the "distance": (as stated in your original question)

number - number.clamp(range)

You can add nonzero? to get nil instead of 0:

(number - number.clamp(range)).nonzero?

For example:

def distance(range, number)
  (number - number.clamp(range)).nonzero?
end

distance(1..2, 3)     #=> 1
distance(-2..21, -10) #=> -8
distance(1..4, 3)     #=> nil

Upvotes: 7

Related Questions