Forum: PC-Programmierung assoziative Arrays bei LUA


von Jürgen W. (lovos)


Lesenswert?

Hallo,
bei
http://www.lua.org/pil/2.5.html
steht was über die Definition von Arrays:
1
    a = {}     -- create a table and store its reference in `a'
2
    k = "x"
3
    a[k] = 10        -- new entry, with key="x" and value=10
4
    a[20] = "great"  -- new entry, with key=20 and value="great"
5
    print(a["x"])    --> 10
6
    k = 20
7
    print(a[k])      --> "great"
8
    a["x"] = a["x"] + 1     -- increments entry "x"
9
    print(a["x"])    --> 11


Darüberhinaus kann man ein normales Array auch direkt angeben, z.B.
1
print( summe( {1,2,3,4,5} ) )
wie geht das bei assoziativen Arrays?
Dinge wie
1
{key1 = value1, key2 = value2}
funktioniert nicht.

von Stefan Salewski (Gast)


Lesenswert?

Jürgen W. schrieb:
> funktioniert nicht.

Wo kein Wille ist, da ist auch kein Weg...

http://www.lua.org/manual/5.1/manual.html

Siehe 2.5.7 - Table Constructors

> table = {e = "a", [3] = "drei"}
> print(table[3])
drei
> print(table["e"])
a
>

Na ja, nun weiß ich, dass auf meinem Rechner sogar Lua installiert ist.

von Jürgen W. (lovos)


Lesenswert?

Das muss daran liegen, dass der Key nicht in Anführungszeichen 
geschrieben darf (im Gegensatz zu der []-Schreibweise)

bei
1
htPar={"index1"="value1"}
ergibt das
1
file.lua:2: '}' expected near '='

Ohne Anführungszeichen funktioniert das aber. Seltsam!

von Udo N. (weinbauer73)


Lesenswert?

Ich kenne zwar Lua nicht, aber nach 
http://lua-users.org/wiki/TablesTutorial kann der Key verschiedenes 
sein, daher darf der nicht in Anführungszeichen stehen.

von Jürgen W. (lovos)


Lesenswert?

> sein, daher darf der nicht in Anführungszeichen stehen.

Im LUA-Tutorial stehen aber die nicht-numerischen Keys ALLE in 
Anführungszeichen. Jeder logisch denkende Mensch würde denken, dass das 
bei einer Direkt-Definition eines Arrays auch so sein muss.

Aber wie so vieles kann man auch das nicht verstehen, sondern sollte es 
einfach zur Kenntnis nehmen

http://www.lua.org/pil/2.5.html
1
    a = {}     -- create a table and store its reference in `a'
2
    k = "x"
3
    a[k] = 10        -- new entry, with key="x" and value=10
4
    a[20] = "great"  -- new entry, with key=20 and value="great"
5
    print(a["x"])    --> 10
6
    k = 20
7
    print(a[k])      --> "great"
8
    a["x"] = a["x"] + 1     -- increments entry "x"
9
    print(a["x"])    --> 11

von Stefan Salewski (Gast)


Lesenswert?

>Jeder logisch denkende Mensch würde denken

Nachlesen oder nachdenken.

Ich würde meinen, man möchte Tipparbeit sparen -- oder tippst Du so 
gerne Anführungszeichen?

Bei Ruby gibt es ähnliche Tipparbeit sparende Konstrukte für 
Initialisierungen, etwa mit dem %w vor einem Array

stefan@AMD64X2 ~/gts $ irb
irb(main):001:0> a = %w[a b c]
=> ["a", "b", "c"]
irb(main):002:0> b = ["a", "b", "c"]
=> ["a", "b", "c"]
irb(main):003:0>

Das macht für mich schon Sinn, aber ich habe auch ein Buch, und lese das 
auch. Lua kenne ich nur dem Namen nach.

von Jürgen W. (lovos)


Lesenswert?

> Das macht für mich schon Sinn

Für mich auch. Ich war lediglich irritiert, dass in den 
Einzelzuweisungen (arr["key"]="value") die Anführungszeichen vorhanden 
sind.

Die Lua-Arrays erinnerten mich an die JSON-Konstrukte.
http://en.wikipedia.org/wiki/JSON

Und da werden auch die Anführungszeichen für Keys verwendet (ob sie 
zwingend notwendig sind weiß ich nicht)
Ohne Anführungszeichen lässt sich der Code viel flüssiger schreiben, 
klar.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Da es in Lua nur einen einzigen zusammengesetzten Datentyp (nämlich die
Table) gibt, mit dem sowohl Arrays als auch Records (Strukturen) darge-
stellt werden, gibt es für die Initialisierung und den Elementzugriff
die Array- und die Record-Syntax. Die Array-Syntax ist die allgemeinere
Form, die Record-Syntax ist syntaktischen Zucker, um Tables wie Struktu-
ren oder Objekte aus anderen Programmiersprachen behandeln zu können.

Array-Syntax:
1
a = { [3]=333, [3.14]="pi", ["pi"]=3.14 }
2
print(a[3])            --> 333
3
print(a[3.14])         --> pi
4
print(a["pi"])         --> 3.14

Der Index kann bspw. ein Integer, FLoat oder String sein. Strings stehen
immer in Anführungszeichen.


Record-Syntax:
1
b = { pi=3.14 }        -- entspricht b = { ["pi"]=3.14 }
2
print(b.pi)            -- entspricht print(b["pi"])

Der Selektor ist ein Identifier und wird (wie auch Variablennamen) ohne
Anführungszeichen geschrieben. Für ihn gelten dieselben Regeln wie für
Variablennamen: Das erste Zeichen muss ein Buchstabe oder Unterstrich
sein, alle nachfolgenden Zeichen Buchstaben, Unterstriche oder Ziffern.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das bedeutet also, daß folgendes identisch ist?
1
a[20] = 1;
2
a["20"] = 1;
Oder wie unterscheidet man das sonst bei der Direktzuweisung?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Johann L. schrieb:
> Das bedeutet also, daß folgendes identisch ist?
> a[20] = 1;
> a["20"] = 1;

Nein, denn 20 (Integer) und "20" (String) sind zwei unterschiedliche
Indizes.

> Oder wie unterscheidet man das sonst bei der Direktzuweisung?

Die Frage habe ich nicht verstanden.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> Johann L. schrieb:
>> Das bedeutet also, daß folgendes identisch ist?
>> a[20] = 1;
>> a["20"] = 1;
>
> Nein, denn 20 (Integer) und "20" (String) sind zwei unterschiedliche
> Indizes.
>
>> Oder wie unterscheidet man das sonst bei der Direktzuweisung?
>
> Die Frage habe ich nicht verstanden.

Ah, ich glaub jetzt hab ich's:
1
table = { 1 = "ein", [2] = "zwei", ["3"] = "drei" }

Der 1. und 3. Schlüssel sind Strings und der 2. ein Integer.

von Jürgen W. (lovos)


Lesenswert?

Ich habe ein kleines Testprogramm geschrieben, um zu sehen, was "intern" 
ankommt: String oder Number/Float.

Im Lua Programm propiere ich alle Kombinationen durch in verschiedenen 
Schreibweise. Dabei verursacht die letzte Schreibweise "{11="str1"}" 
einen Fehler.
1
outputTable({[1]="1"})
2
outputTable({["1"]=1})
3
outputTable({["num"]=1})
4
outputTable({num=1})
5
6
a={}; a[1]="1"
7
outputTable(a)
8
b={}; b["1"]=1
9
outputTable(b)
10
11
--outputTable({11="str1"}) --error


Im C-Programm, was durch die Lua-Funktion "outputTable" aufgerufen wird, 
iteriere ich durch die Tabelle und hänge bei Key und Value ein /S oder 
/N an, je nachdem ob es sich um einen String oder Zahl handelt
1
static int l_outputTable(lua_State *L) {
2
short narg;
3
narg=1;
4
luaL_checktype(L, narg, LUA_TTABLE);
5
{
6
  lua_pushnil(L);
7
  while (lua_next(L, narg) != 0) {
8
    char s2[2][0x20];
9
    unsigned char ii;
10
    for (ii=0;ii<2;ii++) {
11
      if (lua_type(L,-2+ii)==LUA_TSTRING) {
12
        sprintf(s2[ii],"%s/S", lua_tostring(L, -2+ii));
13
      }
14
      else if (lua_type(L,-2+ii)==LUA_TNUMBER)
15
        sprintf(s2[ii],"%.2f/N",lua_tonumber(L, -2+ii));
16
      else sprintf(s2[ii],"TYPE %d",lua_type(L, -2+ii));
17
    }
18
      printf("%s=\t%s\n", s2[0],s2[1]);
19
    lua_pop(L, 1);
20
  }
21
}
22
return 0;
23
}

Die Ausgabe ist wie erwartet, dabei ist zwischen {["num"]=1} und {num=1} 
kein Unterschied.
1
1.00/N=  1/S
2
1/S=  1.00/N
3
num/S=  1.00/N
4
num/S=  1.00/N
5
1.00/N=  1/S
6
1/S=  1.00/N



Nachtrag:
bei der Reihenfolge der indizes spielt die Schreibweise doch ein Rolle:
1
outputTable({[1]="1", ["1"]=1, num=3.14})
erzeugt
1
1.00/N=  1/S
2
num/S=  3.14/N
3
1/S=  1.00/N

von Yalu X. (yalu) (Moderator)


Lesenswert?

Johann L. schrieb:
> Ah, ich glaub jetzt hab ich's:
> table = { 1 = "ein", [2] = "zwei", ["3"] = "drei" }
> Der 1. und 3. Schlüssel sind Strings und der 2. ein Integer.

Theoretisch wäre das so. Allerdings ist der erste Initialisierer in
Record-Syntax gegeben, somit muss der Key hier ein Identifier sein, also
mit einem Buchstaben oder Underscore beginnen, sonst gibt's Gemecker.

Jürgen W. schrieb:
> bei der Reihenfolge der indizes spielt die Schreibweise doch ein Rolle:

Über die Reihenfolge, in der die Elemente intern gespeichert sind, kann
man kaum eine Aussage machen (und sollte es auch nicht), da sie
implementierungsabhängig ist und sich prinzipiell mit jeder neuen
Lua-Version ändern kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.