Feststellen, ob eine Variable innerhalb des Bereichs liegt?


134

Ich muss eine Schleife schreiben, die ungefähr so ​​funktioniert:

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

Aber bisher sind wir in Bezug auf die Syntax die falschen Wege gegangen.

Antworten:


306
wenn zwischen? (1, 10)
  mach was 1 
sonst zwischen? (11,20)
  mach was 2 
...

3
Dies funktioniert auch für Dateund DateTimeObjekte, während ===dies nicht der Fall ist.
Aditya

i.between?(1..10)wird nicht funktionieren (wenn es so ist ..) Ich nehme an, es muss einen Grund dafür geben
Unpolarität

zwischen? würde zwei Parameter benötigen, die keinen Bereich zulassen würden.
Manish Nagdewani

5
ist es inklusive oder exklusiv?
Andrewcockerham

1
@ andrewcockerham Inklusive. 3.between?(1, 3) => true
Tyler James Young

84

Verwenden Sie den ===Operator (oder sein Synonym include?)

if (1..10) === i

1
Hat den schönen Vorteil, auch damit zu arbeiten i, etwas anderes als eine Zahl (wie nil) zu sein
Christoffer Klang

4
Wäre keine sehr effiziente Lösung, wenn die Reichweite erheblich gewesen wäre.
Rthbound

6
Für zukünftige Leser wird der alternative Weg if i === (1..10)nicht funktionieren
Anwar

@rthbound, warum? (1..10000000000000000) ist kein Array. (1..10000000000000000) === 5000000000000000macht gerade einen "Zwischen" -Test unter der Haube
John La Rooy

1
@Anwar kannst du erklären warum es nicht anders funktioniert?
Govind Rai

70

Verwenden Sie, wie @Baldu sagte, den Operator === oder den Anwendungsfall / when, der intern === verwendet:

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

Von allen Antworten ist dies wahrscheinlich auch die leistungsstärkste, wenn Sie mehrere Bereiche haben.
Xentek

40

wenn Sie noch Bereiche verwenden wollten ...

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

8

Normalerweise erzielen Sie eine viel bessere Leistung mit:

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



1

Eine dynamischere Antwort, die in Ruby erstellt werden kann:

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

In diesem Fall sind die "Bereiche" also wirklich nur mit Nullen eingezäunt, um die Randbedingungen zu erfassen.


-2

Für Streicher:

(["GRACE", "WEEKLY", "DAILY5"]).include?("GRACE")

# => wahr

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.