EMZETT.
Login

Kurz: Eine Tabelle ist ein assoziatives Array: Sie ordnet beliebigen Schlüsseln (außer nil) Werte zu. Als Liste, Dictionary, Objekt, Modul, Menge, Warteschlange: alles sind Tabellen.

Teil des Kurses Lua

Kapitel 4 von 8 im Kurs Lua (Abschnitt „Datenstrukturen“). Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Die einzige Datenstruktur

Eine Tabelle ist ein assoziatives Array: Sie ordnet beliebigen Schlüsseln (außer nil) Werte zu. Als Liste, Dictionary, Objekt, Modul, Menge, Warteschlange: alles sind Tabellen.

local liste = {"Apfel", "Birne", "Kirsche"}          -- Schlüssel 1, 2, 3
local person = {name = "Mia", alter = 17}             -- Schlüssel "name", "alter"
local gemischt = {10, 20, x = 1, [100] = "hundert", ["mit leer"] = true}
 
print(liste[1], #liste, person.name, person["alter"], gemischt[100], gemischt["mit leer"])
liste[#liste + 1] = "Dattel"                          -- anhängen
table.insert(liste, "Erdbeere")
table.insert(liste, 1, "Ananas")                      -- an Position einfügen
print(table.concat(liste, ", "))
print(table.remove(liste), table.remove(liste, 1))    -- letztes, erstes entfernen
print(table.concat(liste, ", "), #liste)
 
person.stadt = "Berlin"
person.alter = nil                                     -- löscht den Eintrag
print(person.alter, person.stadt)
print(liste[99], type(liste))

Ausgabe:

Apfel	3	Mia	17	hundert	true
Ananas, Apfel, Birne, Kirsche, Dattel, Erdbeere
Erdbeere	Ananas
Apfel, Birne, Kirsche, Dattel	4
nil	Berlin
nil	table

Durchlaufen

ipairs läuft über die Liste 1, 2, 3 … bis zur ersten Lücke, pairs über alle Einträge (Reihenfolge nicht garantiert):

local t = {"a", "b", "c", x = 1, y = 2}
for i, v in ipairs(t) do io.write(i, "=", v, " ") end
print()
 
local schluessel = {}
for k in pairs(t) do schluessel[#schluessel + 1] = tostring(k) end
table.sort(schluessel)
print(table.concat(schluessel, " "))
 
local preise = {brot = 2.5, milch = 1.2, kaese = 4.0}
local namen = {}
for name in pairs(preise) do namen[#namen + 1] = name end
table.sort(namen)                                      -- für stabile Ausgabe sortieren
for _, name in ipairs(namen) do print(name, preise[name]) end
 
local anzahl = 0
for _ in pairs(preise) do anzahl = anzahl + 1 end
print(anzahl, #preise)                                 -- # zählt nur die Listenfolge

Ausgabe:

1=a 2=b 3=c
1 2 3 x y
brot	2.5
kaese	4.0
milch	1.2
3	0

Sortieren, Kopieren, Auspacken

local z = {5, 2, 9, 1}
table.sort(z)
print(table.concat(z, ","))
table.sort(z, function(a, b) return a > b end)         -- eigene Reihenfolge
print(table.concat(z, ","))
 
local leute = {{n = "Tom", a = 25}, {n = "Mia", a = 17}, {n = "Zoe", a = 17}}
table.sort(leute, function(x, y)
    if x.a ~= y.a then return x.a < y.a end
    return x.n < y.n
end)
for _, p in ipairs(leute) do io.write(p.n, "(", p.a, ") ") end
print()
 
local orig = {1, 2, 3}
local referenz = orig                                  -- gleiche Tabelle!
local kopie = table.move(orig, 1, #orig, 1, {})        -- echte Kopie
orig[1] = 99
print(referenz[1], kopie[1])
 
print(table.unpack({1, 2, 3}))
local a, b = table.unpack({"x", "y", "z"})
print(a, b)
print(select("#", table.unpack({1, nil, 3}, 1, 3)))
print(table.pack(1, nil, 3).n)
print(next({}), next({5}))

Ausgabe:

1,2,5,9
9,5,2,1
Mia(17) Zoe(17) Tom(25)
99	1
1	2	3
x	y
3
3
nil	1	5

Achtung

Tabellen werden als Referenz übergeben. b = a kopiert nicht, sondern zeigt auf dieselbe Tabelle. Für das Kopieren verschachtelter Tabellen schreibst du eine rekursive Funktion.

Verschachtelte Daten und Muster

local firma = {
    name = "Emzett",
    team = {
        {name = "Mia", skills = {"lua", "sql"}},
        {name = "Tom", skills = {"bash"}},
    },
    adresse = {ort = "Berlin"},
}
print(firma.team[1].skills[2], #firma.team, firma.adresse.ort)
print(firma.adresse and firma.adresse.plz or "keine PLZ")
 
local function tiefe_kopie(t)
    if type(t) ~= "table" then return t end
    local k = {}
    for key, v in pairs(t) do k[key] = tiefe_kopie(v) end
    return k
end
local k = tiefe_kopie(firma)
k.team[1].name = "Geändert"
print(firma.team[1].name, k.team[1].name)
 
-- Menge, Zähler, Stapel, Warteschlange
local menge = {}
for _, w in ipairs({"a", "b", "a", "c"}) do menge[w] = true end
local zaehler = {}
for _, c in ipairs({"x", "y", "x", "x"}) do zaehler[c] = (zaehler[c] or 0) + 1 end
print(menge.a, menge.z, zaehler.x, zaehler.y)
 
local stapel = {}
stapel[#stapel + 1] = 1; stapel[#stapel + 1] = 2
print(table.remove(stapel), #stapel)
 
local matrix = {}
for i = 1, 3 do matrix[i] = {} for j = 1, 3 do matrix[i][j] = i * j end end
print(matrix[2][3], #matrix, #matrix[1])

Ausgabe:

sql	2	Berlin
keine PLZ
Mia	Geändert
true	nil	3	1
2	1
6	3	3

Merke

  • Tabellen sind Liste, Dictionary und Objekt in einem; Schlüssel können beliebige Werte sein
  • Listen starten bei 1; #t gibt die Länge; table.insert/remove/concat/sort/unpack
  • ipairs für Listen, pairs für alle Einträge (Reihenfolge nicht garantiert)
  • Tabellen sind Referenzen: Kopieren erfordert eine Funktion
  • Auf nil setzen löscht einen Eintrag

Übungsaufgabe

Zähle die Buchstaben eines Textes in einer Tabelle und gib sie sortiert aus.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Kontrollfluss und Funktionen

Weiter: String-Funktionen und Muster

Alle Kapitel: Lua im Überblick