2016-12-12 1 views
1

Angenommen die folgende Anordnung:Select Array-Element außerhalb der Grenzen absichtlich

a = {"a", "b", "c"} 

Mit a[3], kann ich c zugreifen. Aber wie mache ich die Zeichenfolge "für immer wiederholen" (während es immer noch nur Elemente hat)? Beispiel:

a[4] --will return nil, but I need to to return "a", because 4 is 3 (end of array) + 1 (the element I need). 

Frage:

Wie würde ich a[4] Rückkehr der gleiche Wert wie a[1] machen, wenn a[] aus 3 Elementen besteht?

+0

BTW-A-Tabelle ist kein Array. Eine Tabelle kann eine Sequenz enthalten oder nicht. Ihr "besteht aus 3 Elementen" scheint ein Beispiel für eine [Sequenzlänge] zu sein (https://www.lua.org/manual/5.3/manual.html#3.4.7). Solange Ihre Tabelle eine Sequenz enthält, funktionieren die Algorithmen, die '# t' verwenden. Sie können auch Schlüssel hinzufügen, die keine positiven ganzen Zahlen sind. Wenn Sie positive Ganzzahlschlüssel hinzufügen oder entfernen, dürfen Sie die Sequenz nicht unterbrechen. –

Antwort

4

Sie können entweder sicherstellen, dass der Schlüssel, den Sie verwenden, im richtigen Bereich liegt, oder Sie können diese Logik in ein Metatable umwandeln, indem Sie das Metamethode implementieren. Auf diese Weise teilen Sie Lua mit, was zurückgegeben werden soll, wenn jemand auf einen ungültigen Schlüssel in Ihrer Tabelle zugreift. Siehe http://lua-users.org/wiki/MetamethodsTutorial

local function circle(arr) 
    setmetatable(arr, {__index = 
     function(t, k) 
     if type(k) == "number" and #t > 0 then 
      return rawget(t, (k-1) % #t + 1) 
     end 
     end 
    }) 
end 

local a = {"a", "b", "c"} 
circle(a) 

for j = -10, 10 do 
    print(j, a[j]) 
end 
+0

verdammt war ich fast fertig tippen: D – Piglet

+1

@Piglet - Wahrscheinlich sollten Sie Ihre Tippgeschwindigkeit ausüben :-) –

+0

Das funktioniert gut, und ist auch gültig, wenn 'j' eine wörtliche Zahl ist. Vielen Dank! – devRicher

0

Dies ist nur eine leichte Variation der korrekten Antwort des Egor Skriptunoff, weil ich nicht die Formatierung verloren gehen wollte, wenn sie als Kommentar verfasst.

Meiner Ansicht nach macht dies die Tabellenerstellung zu einer einfacheren Einzelaussage und klarer zu der beabsichtigten Aktion. Es verwendet auch die gleiche Tabelle wie Metatabelle als geringfügige Optimierung.

local 
function circle(arr) 
    function arr.__index(t, k) 
    if type(k) == 'number' and #t > 0 then 
     return rawget(t, (k-1) % #t + 1) 
    end 
    end 
    return setmetatable(arr,arr) 
end 

local a = circle {'a', 'b', 'c'} 

for j = -10, 10 do print(j, a[j]) end 
Verwandte Themen