Suche…


Generisch für Loop

Iteratoren verwenden eine Form der for Schleife, die als generische for-Schleife bekannt ist .

Die generische Form der for Schleife verwendet drei Parameter:

  1. Eine Iteratorfunktion , die aufgerufen wird, wenn der nächste Wert benötigt wird. Es empfängt sowohl den invarianten Status als auch die Steuervariable als Parameter. Rückgabe von nil beendet.
  2. Der invariante Status ist ein Wert, der sich während der Iteration nicht ändert. Es ist normalerweise das Thema des Iterators, z. B. eine Tabelle, eine Zeichenfolge oder Benutzerdaten.
  3. Die Steuervariable repräsentiert einen Anfangswert für die Iteration.

Wir können eine for Schleife schreiben, um alle Schlüssel-Wert-Paare in einer Tabelle mithilfe der nächsten Funktion zu iterieren.

local t = {a=1, b=2, c=3, d=4, e=5}

-- next is the iterator function
-- t is the invariant state
-- nil is the control variable (calling next with a nil gets the first key)
for key, value in next, t, nil do
  -- key is the new value for the control variable
  print(key, value) 
  -- Lua calls: next(t, key)  
end

Standard-Iteratoren

Die Lua-Standardbibliothek bietet zwei Iteratorfunktionen, die mit einer for Schleife zum Durchlaufen von Schlüsselwertpaaren in Tabellen verwendet werden können.

Um eine Sequenztabelle zu durchlaufen, können wir die Bibliotheksfunktion ipairs verwenden .

for index, value in ipairs {'a', 'b', 'c', 'd', 'e'} do
  print(index, value)  --> 1 a, 2 b, 3 c, 4 d, 5 e
end

Um alle Tasten Iterator über und Werte in einer Tabelle können wir die Bibliotheksfunktion verwenden Paare .

for key, value in pairs {a=1, b=2, c=3, d=4, e=5} do
  print(key, value)  --> e 5, c 3, a 1, b 2, d 4  (order not specified)
end

Zustandslose Iteratoren

Sowohl Paare als auch Paare sind zustandslose Iteratoren. Ein statusloser Iterator verwendet zur Berechnung des Iterationswerts nur die generische Steuervariable und den invarianten Status der Schleife .

Paar Iterator

Wir können den statuslosen pairs Iterator mit der next Funktion implementieren.

-- generator function which initializes the generic for loop
local function pairs(t)
  -- next is the iterator function
  -- t is the invariant state
  -- control variable is nil
  return next, t, nil
end

Ipairs Iterator

Wir können den ipairs Iterator in zwei separaten Funktionen implementieren.

-- function which performs the actual iteration
local function ipairs_iter(t, i)
  local i = i + 1  -- next index in the sequence (i is the control variable)
  local v = t[i]   -- next value (t is the invariant state)
  if v ~= nil then
    return i, v    -- index, value
  end
  return nil       -- no more values (termination)
end

-- generator function which initializes the generic for loop
local function ipairs(t)
  -- ipairs_iter is the iterator function
  -- t is the invariant state (table to be iterated)
  -- 0 is the control variable (first index)
  return ipairs_iter, t, 0
end

Charakter Iterator

Wir können neue zustandslose Iteratoren erstellen, indem wir den Vertrag des Generikums for loop erfüllen.

-- function which performs the actual iteration
local function chars_iter(s, i)
  if i < #s then
    i = i + 1
    return i, s:sub(i, i)
  end
end

-- generator function which initializes the generic for loop
local function chars(s)
  return chars_iter, s, 0
end

-- used like pairs and ipairs
for i, c in chars 'abcde' do
    print(i, c) --> 1 a, 2 b, 3 c, 4 f, 5 e
end

Primzahl-Iterator

Dies ist ein weiteres einfaches Beispiel für einen statuslosen Iterator.

-- prime numbers iterator
local incr = {4, 1, 2, 0, 2}
function primes(s, p, d)
   s, p, d = s or math.huge, p and p + incr[p % 6] or 2, 1
   while p <= s do
      repeat
         d = d + incr[d % 6]
         if d*d > p then return p end
      until p % d == 0
      p, d = p + incr[p % 6], 1
   end
end

-- print all prime numbers <= 100
for p in primes, 100 do  -- passing in the iterator (do not call the iterator here)
   print(p)  -->  2  3  5  7  11 ... 97
end

-- print all primes in endless loop
for p in primes do  -- please note: "in primes", not "in primes()"
   print(p)
end

Stateful Iteratoren

Stateful-Iteratoren enthalten einige zusätzliche Informationen zum aktuellen Status des Iterators.

Tabellen verwenden

Der Additionsstatus kann in den generischen invarianten Status der Schleife geschrieben werden .

  local function chars_iter(t, i)
    local i = i + 1
    if i <= t.len then
      return i, t.s:sub(i, i)
    end
  end

  local function chars(s)
    -- the iterators state
    local t = {
      s = s,    -- the subject
      len = #s  -- cached length
    }
    return chars_iter, t, 0
  end

  for i, c in chars 'abcde' do
    print(i, c) --> 1 a, 2 b, 3 c, 4 d, 5 e
  end

Verschlüsse verwenden

Zusätzlicher Status kann innerhalb eines Funktionsabschlusses eingeschlossen werden. Da der Status vollständig im Bereich der Schließung enthalten ist, werden der invariante Status und die Steuerungsvariable nicht benötigt.

  local function chars(s)
    local i, len = 0, #s
    return function() -- iterator function
      i = i + 1
      if i <= len then
        return i, s:sub(i, i)
      end
    end
  end

  for i, c in chars 'abcde' do
    print(i, c) --> 1 a, 2 b, 3 c, 4 d, 5 e
  end

Coroutines verwenden

Ein zusätzlicher Status kann in einer Coroutine enthalten sein, wiederum werden der invariante Status und die Steuerungsvariable nicht benötigt.

  local function chars(s)
    return coroutine.wrap(function()
      for i = 1, #s do
        coroutine.yield(s:sub(i, i))
      end
    end)
  end

  for c in chars 'abcde' do
    print(c) --> a, b, c, d, e
  end


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow