PDA

Volledige versie bekijken : Inhoud array vergelijken


Sebastix
%Europe/Berlin %737 %2008, 17:42
Hallo allemaal!

Ik ben momenteel bezig om een tagcloud script te maken in AS3.0 en daar kom ik het volgende probleem tegen. Zodra ik alle items uit een array met elkaar ga vergelijken en vervolgens iets mee ga doen; gaat het vaak mis en krijg ik de TypeError: Error #1010: A term is undefined and has no properties.

De bedoeling is dat de inhoud van de array met elkaar vergeleken wordt. Zodra een item meer dan 1 keer voorkomt, moet deze worden verwijderd uit de array en wordt er bij de counter 1 opgeteld. Uiteindelijk moet een hele lang array doorlopen worden en het aantal woorden worden geteld die er uiteindelijk in voorkomt (en elk item in de array is 1 woord).

Het script hieronder zal gewoon werken als je het test, maar zodra je een item toevoegt met dezelfde string in de property content achter elkaar...loopt het script vast.

Kan iemand me uitleggen hoe je dit wellicht oplost?
Wellicht pak ik het verkeerd aan op deze manier, dan hoor ik dat ook graag (ik ben nog niet zo heel lang bezig met AS3.0).

package
{
import flash.display.Sprite;

public class test extends Sprite
{
private var eerste:Array = new Array();

public function test()
{
eerste.push({content:"een", count:"0"});
eerste.push({content:"twee", count:"0"});
eerste.push({content:"drie", count:"0"});
eerste.push({content:"twee", count:"0"});
eerste.push({content:"vijf", count:"0"});
eerste.push({content:"twee", count:"0"});
eerste.push({content:"drie", count:"0"});
eerste.push({content:"acht", count:"0"});
eerste.push({content:"twee", count:"0"});
eerste.push({content:"acht", count:"0"});
eerste.push({content:"twee", count:"0"});

var l:Number=eerste.length;
for(var i:Number=0; i<l; i++)
{
//trace("//for1 "+eerste[i].content+" "+i);
for(var z:Number=0; z<l; z++)
{
//trace("////for2 "+z+" "+eerste[i].content+" "+i+" "+eerste[z].content);
if(eerste[i].content === eerste[z].content)
{
eerste[i].count++;
if(eerste[i].count >= 2)
{
eerste.splice(z,1);
l = eerste.length;
//trace("Script moet nu het element verwijderen uit de array welke deze zojuist vond: "+ eerste[i].content);
}
}
}
}
for(var o:Number=0; o<l; o++)
{
trace(eerste[o].content+" "+eerste[o].count);
}
}
}
}

Mvg
Sebastian

Dauntless
%Europe/Berlin %741 %2008, 17:48
Wanneer zal hij juist niet werken ?

Sebastix
%Europe/Berlin %749 %2008, 17:59
Wanneer zal hij juist niet werken ?


Sorry, dat had ik nog niet duidelijk genoeg vermeld inderdaad.

Zodra er items achter elkaar komen te staan die kwa inhoud precies hetzelfde zijn, loopt het script vast met die error.

Dauntless
%Europe/Berlin %766 %2008, 18:24
Dan nog bugt hij niet in elk geval...

Hier is een voorbeeldje dat wel werkt:
for(var i:Number = 0; i<eerste.length; i++)
{
for(var j:Number = 0; j<i; j++)
{
if(eerste[i].content === eerste[j].content)
{
eerste[j].count ++;
eerste.splice(i, 1);
i --;
break;
}
}
}
Je moet wel overal nog 1 bij optellen zodat het klopt.

madweener
%Europe/Berlin %580 %2008, 13:55
waarom kan je geen waarde midden uit de array trekken op deze manier...
ik gebruik een random functie om een nummer terug te krijgen
dit nummer gebruik ik in een namen array en als deze array aangeroepen is en in tekstveld wordt laaten zien dan wil ik hem uit de array verwijderen.
Dit gaat goed als het om het laatste getal gaat maar zodra er een getal als 2 uitkomt die midden in de array valt dan verwijdert hij alles wat erachter zit

gebruik dit stukje code
namen.splice(n,1);

kan iemand mij zeggen waarom?

Dauntless
%Europe/Berlin %585 %2008, 14:02
Splice is hier juist voor hoor:
var ar:Array = new Array(1,2,3);
ar.splice(1,1)
trace(ar);
Output: 1,3

madweener
%Europe/Berlin %587 %2008, 14:05
Waarom doet ie het dan niet bij mij. Ik trace alles en hij doet dit bij mij:

var namen:Array = ["henkjan1", "henkjan2", "henkjan3", "henkjan4", "henkjan5", "henkjan6"];

nummer is nu 0
splice = henkjan1
namen henkjan3,henkjan4,henkjan5,henkjan6
max = 4

nummer is nu 1
splice = henkjan4
namen henkjan3,henkjan6
max = 3

nummer is nu 1
henkjan6
namen henkjan3
max = 2

Dauntless
%Europe/Berlin %587 %2008, 14:06
Geef eens de code die die traces geeft ?

madweener
%Europe/Berlin %589 %2008, 14:08
var n:Number = randRange(0, max);
trace("nummer is nu "+n);
txtNamen.text = namen[n];

namenGehad.push(namen[n]);

trace(namen.splice(n,1));
namen.splice(n,1);

Dauntless
%Europe/Berlin %591 %2008, 14:11
.splice() geeft het element terug dat weggehaald is. Maar het element wordt ook wel degelijk uit de array gehaald. Dus als je dit doet:
trace(namen.splice(n,1));
namen.splice(n,1);
Haal je er twee elementen uit!

madweener
%Europe/Berlin %592 %2008, 14:12
lol ik dacht dat als je traced dat hij het niet daadwerkelijk deed ^^

bedankt!

theFlashWizard
%Europe/Berlin %093 %2008, 02:14
Ik zou een eigen Collection class gaan schrijven om het werken met een collectie wat simpeler te maken. Deze collection kan dan gewoon een array gebruiken om zijn data op te slaan maar je kan de collection class veel handigere methods meegeven als:
add(value:*);
getAt(index:int):*
has(value:*):Boolean
remove(index:int);
enz.
Zo zou je in jou geval kunnen kijken voordat je iets wilt toevoegen of iets al bestaat. Zo niet voeg je het niet toe.
Helaas heb je bij objecten niet genoeg aan het vergelijken van de value (omdat het gewoon altijd andere objecten zijn).
Daarom kun je misschien een volgende method toevoegen aan je collection class.
hadEqualObject(object:IComparible):void
IComparible is dan een interface die een toString en een equals functie beschrijft.
Je kan dan een VO class maken die deze implementeert.
Volgens maak je een TagVO die deze extend. Belangrijk is dan dat je de toString overrided en alle properties in deze toString returnt. Deze kan de equals functie dan gebruiken om te vergelijken. Dit is een erg simpel en snel systeem om value objects te kunnen vergelijken.
(Dit idee heb ik van een collega en dit systeem komt uit Java)

Hoop dat ik je niet teveel overdonder, het zijn wat recente ideetjes die ik al een tijdje wilde delen.