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.