Skip to content

Wie bekomme ich ein Lazy-Array in Ruby?

Lösung:

Mit Ruby 1.9 können Sie die Enumerator-Klasse verwenden. Dies ist ein Beispiel aus den Dokumenten:

  fib = Enumerator.new { |y|
    a = b = 1
    loop {
      y << a
      a, b = b, a + b
    }
  }

  p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Das ist auch ein netter Trick:

  Infinity = 1.0/0

  range = 5..Infinity
  p range.take(10) #=> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

Dieser funktioniert jedoch nur für aufeinanderfolgende Werte.

Kürzlich wurde Enumerable::Lazy zum Ruby-Trunk hinzugefügt. Wir werden es in Ruby 2.0 sehen. Bestimmtes:

a = data.lazy.map(&:split).map(&:reverse)

wird nicht sofort ausgewertet.
Das Ergebnis ist eine Instanz von Enumerable::Lazy, die beliebig weiter verkettet werden kann. Wenn Sie ein tatsächliches Ergebnis erhalten möchten - verwenden Sie #to_a, #take(n) (#take ist jetzt auch faul, benutze #to_a oder #force), etc.
Wenn Sie mehr zu diesem Thema und meinem C-Patch wissen möchten, lesen Sie meinen Blog-Beitrag Ruby 2.0 Enumerable::Lazy

Lazy Range (natürliche Zahlen):

Inf = 1.0/0.0
(1..Inf).take(3) #=> [1, 2, 3]

Fauler Bereich (gerade Zahlen):

(0..Inf).step(2).take(5) #=> [0, 2, 4, 6, 8]

Beachten Sie, dass Sie auch verlängern können Enumerable mit einigen Methoden, um das Arbeiten mit Lazy-Bereichen (und so weiter) bequemer zu machen:

module Enumerable
  def lazy_select
    Enumerator.new do |yielder|
      each do |obj|
        yielder.yield(obj) if yield(obj)
      end
    end
  end
end

# first 4 even numbers
(1..Inf).lazy_select { |v| v.even? }.take(4)

output:
[2, 4, 6, 8]

Mehr Infos hier: http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/

Es gibt auch Implementierungen von lazy_map und lazy_select für die EnumeratorKlasse, die hier zu finden ist: http://www.michaelharrison.ws/welog/?p=163

Click to rate this post!
[Total: 0 Average: 0]



Anderer Beitrag

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.