Определение, находится ли переменная в пределах диапазона?


134

Мне нужно написать цикл, который делает что-то вроде:

if i (1..10)
  do thing 1
elsif i (11..20)
  do thing 2
elsif i (21..30)
  do thing 3
etc...

Но до сих пор пошли по неверному пути с точки зрения синтаксиса.

Ответы:


306
если между? (1, 10)
  сделать вещь 1 
elsif i.between? (11,20)
  сделать вещь 2 
...

3
Это также работает Dateи DateTimeобъекты , а ===не делает.
Адитья

i.between?(1..10)не будет работать (если это так ..), я полагаю, должна быть причина для этого
неполярность

между? потребовалось бы два параметра, это не позволило бы диапазон.
Маниш Нагдевани

5
это включительно или эксклюзивно?
Andrewcockerham

1
@andrewcockerham включительно. 3.between?(1, 3) => true
Тайлер Джеймс Янг

84

Используйте ===оператор (или его синоним include?)

if (1..10) === i

1
Имеет приятное преимущество также работать с iчем-то, кроме числа (например nil)
Кристоффер Кланг

4
Не показалось бы очень эффективным решением, если бы диапазон был значительно большим.
2011 г.

6
Для будущего читателя альтернативный путь if i === (1..10)не сработает
Анвар

@ rthbound, почему? (1..10000000000000000) не массив (1..10000000000000000) === 5000000000000000просто делает «промежуточный» тест под капотом
John La Rooy

1
@ Анвар, не могли бы вы объяснить, почему это не работает по-другому?
Говинд Рай

70

Как сказал @Baldu, используйте оператор === или используйте case /, когда внутренне используется ===:

case i
when 1..10
  # do thing 1
when 11..20
  # do thing 2
when 21..30
  # do thing 3
etc...

из всех ответов, это также, вероятно, самый эффективный, когда у вас есть несколько диапазонов.
xentek

40

если вы все еще хотите использовать диапазоны ...

def foo(x)
 if (1..10).include?(x)
   puts "1 to 10"
 elsif (11..20).include?(x)
   puts "11 to 20"
 end
end

8

Обычно вы можете получить намного лучшую производительность с чем-то вроде:

if i >= 21
  # do thing 3
elsif i >= 11
  # do thing 2
elsif i >= 1
  # do thing 1



1

Более динамичный ответ, который можно встроить в Ruby:

def select_f_from(collection, point) 
  collection.each do |cutoff, f|
    if point <= cutoff
      return f
    end
  end
  return nil
end

def foo(x)
  collection = [ [ 0, nil ],
                 [ 10, lambda { puts "doing thing 1"} ],
                 [ 20, lambda { puts "doing thing 2"} ],
                 [ 30, lambda { puts "doing thing 3"} ],
                 [ 40, nil ] ]

  f = select_f_from(collection, x)
  f.call if f
end

Таким образом, в этом случае, «диапазоны» на самом деле просто ограничены нулями, чтобы поймать граничные условия.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.