• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

multidim. assoc. Array - Elemente zählen

J-C

Lounge-Member
Da man ja bei assoc. Arrays die .length-Eigenschaft nicht nutzen kann, habe ich mal gestöbert und folgende Funktion soll angeblich "helfen":
Code:
function array_length (arrayname)
{
  var i = 0;
  for (var eachElement in arrayname)
  {
    i++;
  }
  return i;
}

Also ich habe folgendes Problem:

ich habe ein multidimensionales, assoziatives array aus einer XML-File geparst.

nun wollte ich die Elemente mit hilfe der o.g. selbstgebauten Funktion zählen. - klappt leider nicht. ich bekomme als "länge" immer 1 zurück.


mein Array ist (beispielhaft) wie folgt aufgebaut:
Code:
arrCards[cardType] = [];
arrCards[cardType][curCardID] = [];
arrCards[cardType][curCardID]["cardName"] = XML_Name;
arrCards[cardType][curCardID]["kosten"] = [];
arrCards[cardType][curCardID]["kosten"]["arbeiter"] = XML_Arbeitskosten;
arrCards[cardType][curCardID]["kosten"]["leiter"] = XML_Leiterkosten;


so ... nun möchte ich gern die Anzahl der Karten vom selben Cardtype wissen.

also dachte ich, ich kann mit der o.g. Funktion über das Array arrCards[speziellerCardType] "zählen" lassen ... wie gesagt, ich bekomme immer als ergebnis "1" zurück - was definitiv nicht der wahrheit entspricht :D

was mach ich nun bzw was mach ich falsch?
 
Ich nehme an das ist ähnlich wie JS, warum verwendest du überhaupt ein Array? Das ist nur ein Objekt, den overhead eines Arrays brauchst du nicht.

Dann lass dir mal ausgeben was du hier genau zählst:
PHP:
function array_length(arrayname)
{
  var i = 0;
  
  for (var eachElement in arrayname)
  {
	alert(eachElement + '=' + arrayname[eachElement]);
	i++;
  }
  return i;
}
 
Ich gehe mal davon aus, dass CardType und CardID nicht fortlaufend sind, weswegen Du nicht einfach mit length arbeiten kannst.
Allerdings frage ich mich, ob es applikativ erforderlich ist über den CardType auf eine bestimmte CardID zuzugreifen. Wenn es tatsächlich nicht gebraucht wird, dann würde ich die CardID als Eigenschaft des darunterliegenden Objektes ablegen und das jetzige assoziative Array "CardID" zu einem gewöhnlichen Array umstellen.
Wenn Du den Zugriff auf die CardID brauchst, so steht dem auch nichts im Wege, könntest Du doch eine zweite Datenstruktur anlegen, welche alle Karten über ihre CardID zugänglich macht. Denn es spricht nichts dagegen ein Objekt, bzw. dessen Referenz in zwei verschiedenen Datenstrukturen zu speichern.
Allerdings solltest Du dann den CardType ebenfalls nochmal im Objekt hinterlegen, sonst geht diese Information nur durch aufwändiges Suchen hervor.

Auf jeden Fall solltest Du so die length Eigenschaft für alle Karten eines Kartentyps nutzen können, denn es handelt sich um ein ordinäres Array.

Prinzipiell sollte das andere aber auch funktionieren, Du machst also irgendwas anderes falsch. Vielleicht ist der Parser kaputt und Du hast tatsächlich nur einen Eintrag im Arrray.
 
das kann ich mir leider nicht ausgeben lassen, weil flash arrays irgendwie nicht so einfach ausgeben mag - ich bekomme ein sehr aussagekräftiges:
undefined,undefined,undefined,undefined, ....

und das auch, wenn ich das array direkt anspreche - nur, wenn ich gezielte elemente anspreche (also die gesamthierarchie) - stimmt alles

und diese "for in" - schleife ... ist auch so eine sache - das element ist irgendwie nicht näher bestimmt - er klappert einfach nur das array durch ... sowas wie eine foreach-schleife wäre toll


-------------------------------------

@ albu - also ich schlüssle das mal ein wenig weiter auf:
also:

Code:
arrCards = [];
arrCards["herz"] = [];
arrCards["kreuz"] = [];
...

arrCards["herz"]["koenig"] = [];
arrCards["herz"]["dame"] = [];
...
// die bezeichnungen sind jetzt einfach mal wirr gewählt
arrCards["herz"]["koenig"]["kosten"] = [];
arrCards["herz"]["koenig"]["nutzen"] = [];
...
arrCards["herz"]["koenig"]["kosten"]["gold"] = 20;
arrCards["herz"]["koenig"]["kosten"]["silber"] = 15;
arrCards["herz"]["koenig"]["kosten"]["bronze"] = 5;

so ... ähnliche Einträge auch für arrCards["herz"]["dame"]
und dann auch bei arrCards["kreuz"]

das ganze - kann man sich denken, läuft auf ein Spiel hinaus, in welchem man verschiedene kartenklassen hat. die kartenklassen sind (eindeutig) Kartenzugeordnet (jede karte nur in einer klasse) - die karten haben eigenschaften, die sich in feste kategorien unterteilen - und diese eigenschaften wiederum sind einzeln in jeder kategorie aufgelistet.

nun brauch ich halt eine möglichkeit, die anzahl der karten in jeder klasse zu bestimmen

wenn ich jetzt diese weiter oben aufgeführte funktion zum zählen verwende - also:
Code:
function array_length (arrayname)
{
	var anzahl = 0;
	for (var cn in arrCards[arrayname]){ anzahl++; trace(arrayname+"--->"+anzahl);}
	
	return anzahl;
}

array_length("herz");

bekomm ich als anzahl immer eine "1" zurück - obwohl in arrCards["herz"] nicht nur 1 element drin ist.
 
Zuletzt bearbeitet:
verdammt ich seh grad - in dieser reduzierten form klappt die zählerei ... WAHHHHHHHHHHHHHHHHHH
 
hmmm - du meinst ich sollte objekte erzeugen? (passiert das nicht eh, wenn ich ein assoc-array erzeuge????) ... jedenfalls hat albu recht - in der verkürzten version klappt es ... irgendwie scheint bei mir ein fehler in der umwandlung XML> array zu stecken
 
so - also ich hab's jetzt nochmal in "klein" versucht - mit keinem zufriedenstellenden Ergebnis:

Code:
function array_length (arrayname)
{
	var anzahl = 0;
	for (v=0;v<arrTest[arrayname].length;v++){
		anzahl++;
	}
	
	return anzahl;
}

arrTest = [];
myVar = "eins";

arrTest[myVar] = [];
arrTest[myVar]["kosten"] = 1;
arrTest[myVar]["groesse"] = 2;


trace(arrTest[myVar].length);
trace(array_length(myVar));
trace(arrTest);

schon bei dieser simplen Konstruktion bekomme ich "0" als länge zurückgegeben.

bei der Komplexeren Konstruktion "zählt" Flash scheinbar die unterelemente mit. Ich hab's nochmal als .ZIP-File angehängt.

ich habe gedacht, daß die Länge eines Arrays nur durch seine Hauptelemente bestimmt wird - dem ist scheinbar nicht so .... ???

Bsp
Code:
myArr = [];


myArr["herz"] = [];  // jetzt sollte myArr eine length von "1" haben
myArr["herz"]["koenig"] = "irgendwas";
myArr["herz"]["dame"] // jetzt sollte myArr immernoch eine length von "1" haben ... in meinem Programm ist es dann schon "3" lang ....?????


ich versteh die welt nicht mehr.
Vllt soltle ich doch mit KLassen & objekten arbeiten ... *seufz* ... wenn ich da nur dahintersteigen würde :D
 

Anhänge

  • siegewars.zip
    13,7 KB · Aufrufe: 2
Ein "assoziatives Array" ist in JS kein Array, daher behaupte ich auch, es gibt sie nicht in JS. Es ist einfach ein Objekt, aber das sagte ich ja bereits.
 
in AS ists irgendein mix aus array und objekt.
aber was bringt mir die erkenntnis????

wenn ich mir mal die ausgabe anschaue ... ergeben sich seltsame sachen.
Ich lasse bei jedem durchlauf, wenn ich das array anlege, den kartentyp, die karte und die daruas resultierende länge des Arrays[kartentyp] anzeigen.

folgendes kommt dabei heraus:
Code:
Fundament
Turm
Schloß
Fort
Festung
Babylon
Reserve
Kartentyp: castlecards:8 // eigentlich sollten es "7" sein .. nagut - 1 mehr könnte nachvollziehbar sein


Wand
Mauer
Verteidigung
Befestigung
Bollwerk
Kartentyp: fencecards:14 // eigentlich sollte arrCards["fencecards"] nur 5 elemente lang sein - aber scheinbar wird "weitergezählt" -> dennoch 1 element mehr.


Hindernis
Graben
Fluss
Kluft
Abgrund
Kartentyp: moatcards:19 // wenn er jetzt immer die gesamtanzahl anzeigt - wieso dann müßte es (nach obigen "fehlerschema") jetzt "20" heißen ...


Steine beschwören
Schaufeln beschwören
Waffen beschwören
Mana beschwören
Kartentyp: conjurecards:23 // 19+4 -> also scheint die anzahl, um die es größer wird, zu stimmen? ....


Schule
Gräber
Rekrutierung
Zauberer
Kobolde
Kartentyp: recruitcards:27 // wieso ist 23+5 elemente nur 27???


Steine zerstören
Schaufeln zerstören
Waffen zerstören
Mana zerstören
Kartentyp: crushcards:31 // jetzt stimmt es wieder


Arbeiter-Assassine
Gräber-Assassine
Ritter-Assassine
Zauberer-Assassine
Kartentyp: assassincards:35 // stimmt


Bogenschütze
Ritter
Schwadron
Katapult
Sprengmeister
Kartentyp: attackcards:46 // öh ... 35+5 ist 46?????


Dieb
Meisterdieb
Saboteur
Meistersaboteur
Bestechung
Kartentyp: specialcards:47 // 46+5 ist 47????


Drachen
Todeshauch
Kartentyp: heavyattackcards:45 // 47+2 ist 45???????


Fluch
Segen
unheiliger Segen
2 Runden Verlängern
3 Runden Verlängern
5 Runden Verlängern
Kartentyp: rarecards:54 // und 45+6 ist 54? ja leckt's mich doch am oasch ...


also die _wirkliche_ gesamtzahl der karten ist tatsächlich 53. dennoch sollten die einzelzahlen, die hier immer größer werden eigentlich immer die anzahl der beinhalteten Karten anzeigen ...
 
Das bringt dir die Erkenntnis, dass du keine Funktionen eines arrays anwenden kannst und die Anzahl der Eignschaften, die du ermitteln willst bekommst du mit deiner Ursprünglichen Funktion.
PHP:
arrTest = {};
myVar = "eins";

arrTest[myVar] = {};
arrTest[myVar]["kosten"] = 1;
arrTest[myVar]["groesse"] = 2;
function object_length(obj) {
	var count = 0;
	for(var attr in obj)  count++
	return count;
}
trace(object_length(arrTest[myVar]));

function trace(arg) {alert(arg);}
 
also die _wirkliche_ gesamtzahl der karten ist tatsächlich 53. dennoch sollten die einzelzahlen, die hier immer größer werden eigentlich immer die anzahl der beinhalteten Karten anzeigen ...
Ich würde sagen Du machst irgendwas beim Zusammenbauen der Arrays falsch (ich habe mir Dein .zip noch ned angeschaut).
Vielleicht solltest Du mit Zwischenvariablen arbeiten und erst die Unterobjekte zusammenbauen, um sie als ganzes in das Hauptobjekt reinzufummeln.
Vielleicht solltest Du auch mal spasseshalber "= new Object ();" statt "= [];" schreiben, denn das was Du da hast sind Objekte und keine Arrays. Dass Objekte-Eigenschaften und -Methoden über den Array-Operator abgerufen werden können, ist nur ein netter Service, der so manches eval spart.
 
Wo es aber auf jeden Fall Probleme geben dürfte ist die ID. Die ist numerisch und wenn Du nun diese Zahl als Index für Dein Array / Object hernimmst, dann ist klar, dass ihr beide ein Problem habt Arrays und Objekte auseinander zu halten. Wenn Du ein Array anlegst und dann mit Zahlen auf bestimmte Elemente zugreifst, dann erweitert Flash die Größe des Arrays auf die notwendige Anzahl. Array Index 53 ist das 54te Element und somit ergibt .length 54, obwohl weniger Elemente enthalten sind. Das kannst Du auch sehr schön sehen, wenn Du vom Player mal Deine Variablen ausgeben läßt (im Menü Debuggen)

Du solltest also Deine Datenstruktur massivst überdenken. Wenn Du ein assoziatives Array haben willst, dann lege kein Array an, sondern ein Object. Und dann solltest davon absehen Zahlen für den Zugriff zu verwenden, weil Zahlen als Bezeichner nicht erlaubt sind. ``"id_" + cardID´´ wäre dagegen in Ordnung.
 
hmmm - ich glaub, ich versuch es doch mal mit objects ... *seufz*

der debugger gibt mir außer mein XML-Variable einfach mal gar keine variablen aus ... ????
 
Zurück
Oben