assoziative Arrays bei LUA

OP #2871044
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.
OP #2871488
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
Gast #2871606
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.
OP #2871615
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.
Moderator #2872621
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.
Persönliche Seite #2873139
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.
OP #2873158
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
Moderator #2873351
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren