[js] maken van associatieve array: krijg altijd een key 0

Pagina: 1
Acties:

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ben niet zo'n held in JS, dus heb uitgebreid de search en google gebruikt, maar kon gek genoeg geen oplossing voor m'n (volgens mij simpele) probleem vinden.

Ben twee manieren tegengekomen om een associatieve array te maken:

1
JavaScript:
1
2
3
4
var assocarr = [];
assocarr['1'] = 'iets';
assocarr['2'] = 'nog iets';
assocarr['3'] = 'en nog iets';

of
2
JavaScript:
1
2
3
4
var assocarr = new Array();
assocarr['1'] = 'iets';
assocarr['2'] = 'nog iets';
assocarr['3'] = 'en nog iets';


Dit heeft alleen als uiterst irritant gevolg dat er ook een assocarr[0] gemaakt wordt met een lege waarde. En dat wil ik niet :( , want dat gooit de rest van m'n code in de war.
Dus je voelt 'm al aankomen: Hoe maak ik een associatieve array aan zonder dat eerste lege element ??

(Voor degene die het doel nog willen weten: ben bezig met select-menuutjes waarbij de waarde van de 1 de ander moet beïnvloeden. Omdat de waardes uit een database getrokken worden en ik daarbij met IDs en overeenkomstige namen te maken heb moet ik de key van die elementen kunnen beïnvloeden)

[ Voor 16% gewijzigd door marty op 08-12-2003 01:26 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:55

crisp

Devver

Pixelated

assocarr[0] bestaat niet; hij is nl undefined:

JavaScript:
1
alert(typeof assocarr[0]); // 'undefined'


verder is een associatieve array nogal onzinnig als je vervolgens cijfers voor je indices gaat gebruiken vanwege de weaktyping in JS:

JavaScript:
1
2
assocarr['1'] = 'iets'; alert(assocarr[1]); // 'iets'
assocarr[1] = 'iets'; alert(assocarr['1']); // 'iets'

Intentionally left blank


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
crisp schreef op 08 december 2003 @ 08:26:
assocarr[0] bestaat niet; hij is nl undefined:

JavaScript:
1
alert(typeof assocarr[0]); // 'undefined'
ok, waarschijnlijk heb ik het niet helemaal correct neergezet, maar zoals ik al zei, ben geen held in javascript :). Neemt niet weg dat er een eerste leeg/undefined element in die array komt die ik daar niet wil hebben. Als ik namelijk vervolgens door de array ga loopen, dan heb ik er last van.
Dus weet je ook hoe ik er vanaf kan komen?
verder is een associatieve array nogal onzinnig als je vervolgens cijfers voor je indices gaat gebruiken vanwege de weaktyping in JS:

JavaScript:
1
2
assocarr['1'] = 'iets'; alert(assocarr[1]); // 'iets'
assocarr[1] = 'iets'; alert(assocarr['1']); // 'iets'
ja, maar ik wil wel bij 1 kunnen beginnen ipv 0, en soms is het ook niet allemaal opvolgend. vandaar dat ik zelf de keys van die array wil kunnen bepalen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:55

crisp

Devver

Pixelated

je moet een array zien als een speciaal type object. Elk niet bestaande property is per definitie undefined. Als je door je properties heen wilt lopen kan dat met een for...in constructie:

JavaScript:
1
2
3
4
5
6
7
8
var ar = [];
ar['1'] = 'iets';
ar['2'] = 'nog iets';
ar['3'] = 'iets anders';

for (var a in ar) {
  alert(a+': '+ar[a]);
}

Intentionally left blank


  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 25-02 11:17

Clay

cookie erbij?

je kan toch ook gewoon vanaf 1 beginnen te loopen? :? en met een simpele check voorkom je errors.

code:
1
2
3
4
5
6
7
8
9
10
11
12
var arr = [];

arr[1] = 'fiets';
arr[2] = 'auto';
arr[10] = 'brommer';

alert(arr.length);

for(var i=1; i<arr.length; i++) {
   if(!arr[i]) continue;
   alert(arr[i]);
}

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
crisp schreef op 08 december 2003 @ 10:47:
je moet een array zien als een speciaal type object. Elk niet bestaande property is per definitie undefined. Als je door je properties heen wilt lopen kan dat met een for...in constructie:

JavaScript:
1
2
3
4
5
6
7
8
var ar = [];
ar['1'] = 'iets';
ar['2'] = 'nog iets';
ar['3'] = 'iets anders';

for (var a in ar) {
  alert(a+': '+ar[a]);
}
Dat wist ik al, maar nogmaals: daar krijg ik dus problemen mee als die undefined element er in zit.

zal m'n hele code ff geven: (heb ik overigens ook van jou gejat, uit een ander topic ;) en ben die vervolgens aan gaan passen)

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<html>
<head>
<title>test</title>
<script type="text/javascript">
// var destination = new Array();
var destination = [];
destination['1'] = 'Algarve';
destination['2'] = 'Porto Santo';
destination['3'] = 'Turkije';

// var destination = ['Algarve','Porto Santo','Turkije'];

var rooms = [];
rooms['1'] = ['1 persoons','2 persoons'];
rooms['2'] = ['Suite 1','Suite 2','Suite 3'];
rooms['3'] = ['zeezicht','landzicht'];

var datetos = [];
datetos['1'] = ['1','3','5','7'];
datetos['2'] = ['2','4','6'];
datetos['3'] = ['10','11'];

function fillSelect(el, arr)
{
    el.options.length = 0;
    for (var i in arr)
    {
        el[i] = new Option(arr[i], i);
    }

    el.selectedIndex = 1;
    if (typeof el.onchange == 'function')
    {
         el.onchange();
    }
}
</script>
<body onload="fillSelect(document.forms['BookingFrm'].elements['destination'], destination)">
<form id="BookingFrm" action="#">

<select style="width:120px" name="destination"
    onchange="fillSelect(this.form.elements['Room'], rooms[this.options[this.selectedIndex].value]);
        fillSelect(this.form.elements['DateTo'], datetos[this.options[this.selectedIndex].value]);">
</select><br />
<select style="width:120px" name="Room"></select>
<select style="width:120px" name="DateTo"></select>
</form>
</body>
</html>


als ik
var destination = [];
destination['1'] = 'Algarve';
destination['2'] = 'Porto Santo';
destination['3'] = 'Turkije';

gebruik, dan krijg ik van mozilla de melding:
Error: uncaught exception: [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "<unknown>"]
en als ik
var destination = ['Algarve','Porto Santo','Turkije'];
gebruik, dan gaat het goed.

en mijn verklaring was dus dat lege element, want als ik de arrays alert, dan begint destination met een , ipv Algarve

edit:
dit is uiteraard nog niet hoe het uiteindelijk wordt, maar dit is waar ik nu op stuk loop

[ Voor 40% gewijzigd door marty op 08-12-2003 10:58 ]


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Clay schreef op 08 december 2003 @ 10:51:
je kan toch ook gewoon vanaf 1 beginnen te loopen? :? en met een simpele check voorkom je errors.

code:
1
2
3
4
5
6
7
8
9
10
11
12
var arr = [];

arr[1] = 'fiets';
arr[2] = 'auto';
arr[10] = 'brommer';

alert(arr.length);

for(var i=1; i<arr.length; i++) {
   if(!arr[i]) continue;
   alert(arr[i]);
}
zie nu je reply pas.
Nee, da's niet echt een optie. Ik wil graag met 1 functie alles op kunnen lossen, anders wordt het zo'n zootje en er komen ook nog een paar selectboxjes bij waarvan zowel de key als de value een niet-numerieke waarde moeten kunnen bevatten. Ik blijf dus liever gebruik maken van die for (var .. in ..) methode

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:55

crisp

Devver

Pixelated

zoiets misschien:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function fillSelect(el, arr)
{
    el.options.length = 0;
    var j = 0;
    for (var i in arr)
    {
        el[j++] = new Option(arr[i], i);
    }

    el.selectedIndex = 0;
    if (typeof el.onchange == 'function')
    {
         el.onchange();
    }
}

Intentionally left blank


Verwijderd

marty schreef op 08 december 2003 @ 12:03:
[...]
Nee, da's niet echt een optie. Ik wil graag met 1 functie alles op kunnen lossen, anders wordt het zo'n zootje en er komen ook nog een paar selectboxjes bij waarvan zowel de key als de value een niet-numerieke waarde moeten kunnen bevatten. Ik blijf dus liever gebruik maken van die for (var .. in ..) methode
Arrays hebben nou eenmaal bepaalde eigenschappen. Ik snap niet waarom je zo'n probleem hebt om daar omheen te coden. for i in Array loopt gewoon door alle eigenschappen, dus ook door methoden, e.d. Dit moet je afvangen als je wilt dat je script werkt.

Overigens heb ik pasgeleden nog een vrij eenvoudig en generiek scriptje gepost:
[rml]Blues in "[ Javascript] Array + <select> opties"[/rml]
Hiermee kun je heel eenvoudig meerdere afhankelijke selects coden.

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 27-05 10:42
JavaScript kent alleen numerieke arrays, die op 0 beginnen en dan doortellen. En element op zeg de 4e plaats invoegen heeft als resultaat dat er daarvoor lege entries aangemaakt worden.

Als je echt een key => value structuur wilt hebben moet je een object nemen, dan kun je ook numerieke keys gebruiken.

//edit:
Ook nog ff de syntax dan maar:

code:
1
2
3
var RealyAssoc = new Object();
RealyAssoc["blaat"] = "boink";
RealyAssoc["nogwat"] = "etc.";


Of korter:

code:
1
var ReallyAssoc = {"blaat":"boink", "nowat":"etc"};

[ Voor 62% gewijzigd door Morrar op 08-12-2003 12:43 ]


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
crisp schreef op 08 december 2003 @ 12:05:
zoiets misschien:
[..knip..]
ja! :)
Nu snap ik ook pas waarom ie daar precies op vast liep. Thnx.
Verwijderd schreef op 08 december 2003 @ 12:29:
[...]
Arrays hebben nou eenmaal bepaalde eigenschappen. Ik snap niet waarom je zo'n probleem hebt om daar omheen te coden.
=>
:)
for i in Array loopt gewoon door alle eigenschappen, dus ook door methoden, e.d. Dit moet je afvangen als je wilt dat je script werkt.
Aha...ik ben alleen php gewend en een heeel klein beetje python, maar het idee dat arrays methoden hebben vind ik maar wazig :? daar had ik dus ook niet op gerekend... (en heb eerlijk gezegd nogal moeite me daar iets bij voor te stellen)
Overigens heb ik pasgeleden nog een vrij eenvoudig en generiek scriptje gepost:
[rml]Blues in "[ Javascript] Array + <select> opties"[/rml]
Hiermee kun je heel eenvoudig meerdere afhankelijke selects coden.
No offense, maar ik vind die van crisp wat doorzichtiger :)
Morrar schreef op 08 december 2003 @ 12:39:
JavaScript kent alleen numerieke arrays, die op 0 beginnen en dan doortellen. En element op zeg de 4e plaats invoegen heeft als resultaat dat er daarvoor lege entries aangemaakt worden.

Als je echt een key => value structuur wilt hebben moet je een object nemen, dan kun je ook numerieke keys gebruiken.

//edit:
Ook nog ff de syntax dan maar:

code:
1
2
3
var RealyAssoc = new Object();
RealyAssoc["blaat"] = "boink";
RealyAssoc["nogwat"] = "etc.";


Of korter:

code:
1
var ReallyAssoc = {"blaat":"boink", "nowat":"etc"};
Dat van die objecten hou ik in m'n achterhoofd voor een volgend keertje. Thnx

[ Voor 5% gewijzigd door marty op 08-12-2003 13:15 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:55

crisp

Devver

Pixelated

Verwijderd schreef op 08 december 2003 @ 12:29:
[...]
for i in Array loopt gewoon door alle eigenschappen, dus ook door methoden, e.d. Dit moet je afvangen als je wilt dat je script werkt.
[...]
Dat geldt (gelukkig) alleen voor custom methods die je dmv prototyping hebt toegekend, en daar is best omheen te werken.

De opmerking van Morrar mbt Objects is ook wel valide, maar ik zie een Array eigenlijk ook al als een object, maar dan met wat specifieke methods en properties en een andere constructor ;)

Intentionally left blank


Verwijderd

marty schreef op 08 december 2003 @ 13:10:
No offense, maar ik vind die van crisp wat doorzichtiger :)
No offense taken :P die van mij is ook puur geexpirimenteer in hoe algemeen zoiets opgezet kan worden.

Het voordeel van die van mij is dat je een hierarchische boom van opties opgeeft die arbitrair diep kan zijn. De benodigde SELECTs en OPTIONs worden automatisch gerenderd. Die hoef je dus niet zelf in de HTML te zetten.

  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 25-02 11:17

Clay

cookie erbij?

Dat geldt (gelukkig) alleen voor custom methods die je dmv prototyping hebt toegekend, en daar is best omheen te werken.
ter verduidelijking, dit is het probleem dus:

code:
1
2
3
4
5
6
7
8
9
Object.prototype.woei = function() {
    alert('woei');
}

var dinges = [1,2,3,4];

for(var i in dinges) {
    alert(dinges[i]);
}


de "woei" functie wordt nu ook ge'alert. Omdat een array gewoon een object is. En wat betreft die notatie van:

code:
1
var ReallyAssoc = {"blaat":"boink", "nowat":"etc"};


de qoutes om blaat en nowat kunnen weggelaten worden. Die hoeven alleen als je tekens wil gebruiken die in normale variabelenamen niet mogen. Je kan dat ook gebruiken om op getallen de indiceren, ala {0:'dinges', 1:'haha'}, maar dat errort op ie5.0 dacht ik.

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 27-05 10:42
crisp schreef op 08 december 2003 @ 13:21:
[...]
De opmerking van Morrar mbt Objects is ook wel valide, maar ik zie een Array eigenlijk ook al als een object, maar dan met wat specifieke methods en properties en een andere constructor ;)
Tsja daar ben ik het dus niet helemaal mee eens, maar in veel programmeertalen is het onderscheid wel steeds minder. Een Array was eigenlijk puur een data-structuur, dus zonder eigen methodes en puur om een verzameling van dingen in te rammen.

Een object daarentegen is veel meer. Het heeft weliswaar ook ruimte voor eigen data (eigen variabelen i.p.v. data op nummers geordend), maar objecten kunnen ook in hierarchieen gestructeerd worden en eigen (d.w.z. zelf gedefinieerde) methodes hebben. Arrays hebben alleen dimensies en offiecieel geen eigen methoden. Dat je in JS het prototype van het object kan gaan versleutelen laat ik maar even voor wat het is, omdat ik het eik een beetje vreemde programmeermanier vind.

Noem me een mierenneuker, maar er was ooit wel een vrij helder onderscheid tussen beiden ;) Dat tegenwoordig iedereen een Array implementeerd als een soort gedegenereerd object is zeker waar, en misschien ook wel handiger

Verwijderd

Morrar schreef op 08 december 2003 @ 14:26:
Tsja daar ben ik het dus niet helemaal mee eens, maar in veel programmeertalen is het onderscheid wel steeds minder. Een Array was eigenlijk puur een data-structuur, dus zonder eigen methodes en puur om een verzameling van dingen in te rammen.
Dat is het in JavaScript eigenlijk nooit geweest:
JavaScript:
1
2
var a = new Array();
alert(typeof a); // ==> 'object';
Arrays hebben alleen dimensies en offiecieel geen eigen methoden. Dat je in JS het prototype van het object kan gaan versleutelen laat ik maar even voor wat het is, omdat ik het eik een beetje vreemde programmeermanier vind.
Geen eigen methoden? sort(), splice(), join(), etc zijn toch echt Array-specifieke methoden. Of bedoel je iets anders? Het versleutelen van prototypen is juist heel handig: je kunt zo nieuwe methoden toevoegen. Array.memberOf() bijvoorbeeld, of Array.shuffle().

  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 27-05 10:42
Verwijderd schreef op 08 december 2003 @ 14:42:
Dat is het in JavaScript eigenlijk nooit geweest:
Tsja alles (window, frame, Math) is een voorgedfinieerd object in JS, dus dat is niet zo vreemd. Het gaat mij meer om het theoretische onderscheid, en dat was er wel in JS, volgens mij is het nog niet zo lang dat je met prototype de voorgedefinieerde constructen kunt gaan aanpassen / uitbreiden.
Verwijderd schreef op 08 december 2003 @ 14:42:
Geen eigen methoden? sort(), splice(), join(), etc zijn toch echt Array-specifieke methoden. Of bedoel je iets anders? Het versleutelen van prototypen is juist heel handig: je kunt zo nieuwe methoden toevoegen. Array.memberOf() bijvoorbeeld, of Array.shuffle().
Ik bedoelde methoden die je zelf kunt definieren, de methoden die je noemt zijn voorgedefinieerd. Ik vind het wat vreemd dat je zelf met de standaard objecten kunt gaan lopen klooien, hoewel het op zich handig is. Als je niet het prototype (het standaardpbject dus) kon aanpassen zou je een iegen 'kopie'-object maken met methoden. Neem bijvoorbeeld een object als "PlayList":

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function PlayList()
{  this.titles = new Array();

   this.add = PlayListAdd;
   this.shuffle = PlayListShuffle;
   //etc.
}

function PlayListAdd(Title) { //bla }
function PlayListShuffle() { //bla }

MyPlayList = new PlayList();
MyPlayList.add("Nummertje");
MyPlayList.add("Nummertje2");
MyPlayList.shuffle();


Het voordeel is nu dat de shufflemethode niet aan de standaard gehangen wordt. Stel je voor dat er ergens nog een object met een andere shufflemethode gedefinieerd wordt. Als beide objecten hun shufflemethodes aan de standaard hadden gehangen had dat vreemde gevolgen gehad. Daarom laat ik de standaardobjecten liever voor wat ze zijn. Maar da's mijn eigen voorkeur...

//Misschien raakt deze discussie nu een beetje off-topic? :)

[ Voor 5% gewijzigd door Morrar op 08-12-2003 15:05 ]


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Morrar schreef op 08 december 2003 @ 15:01:
[...]
//Misschien raakt deze discussie nu een beetje off-topic? :)
nee, nee. ga vooral door, want dit verduidelijkt voor mij een hoop! :)

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 15:55

crisp

Devver

Pixelated

Morrar schreef op 08 december 2003 @ 15:01:
[...]

Tsja alles (window, frame, Math) is een voorgedfinieerd object in JS, dus dat is niet zo vreemd. Het gaat mij meer om het theoretische onderscheid, en dat was er wel in JS, volgens mij is het nog niet zo lang dat je met prototype de voorgedefinieerde constructen kunt gaan aanpassen / uitbreiden.
[...]
Volgens mij is dat al sinds de komst van de prototype property in javascript 1.1 (IE3 en Netscape 2 meen ik) mogelijk. Het toevoegen van methods aan standaard objecten heeft ook wel degelijk nut, bijvoorbeeld om nieuwere methoden ook in oudere browsers beschikbaar te maken zoals bijvoorbeeld de Array.splice() method in IE5.0.
Uiteraard zal je voor specifieke zaken eerder je eigen object aanmaken dan de standaard objecten extenden, maar ik weet niet beter dan dat het zo'n beetje altijd al mogelijk was...

[ Voor 3% gewijzigd door crisp op 08-12-2003 15:29 ]

Intentionally left blank


  • Clay
  • Registratie: Oktober 1999
  • Laatst online: 25-02 11:17

Clay

cookie erbij?

Naast de bestaande objecten aanpassen kan je natuurlijk ook overerving gebruiken, b.v.

code:
1
2
3
4
5
6
7
8
function PlayList() {
    Array.apply(this, arguments);
}

PlayList.prototype = new Array();
PlayList.prototype.add = function(song) {
    this.push(song);
}


zo is playlist een soort Array. Maar de standaard array uitbreiden met (generieke!) handige functies vind ik niet zo'n ramp eigenlijk :) 't is toch maar per project/page. zo kan je het String object b.v. .intValue() en .floatValue() geven. Veel kwaad kan dat imo niet.

Instagram | Flickr | "Let my music become battle cries" - Frédéric Chopin


  • Morrar
  • Registratie: Juni 2002
  • Laatst online: 27-05 10:42
Clay schreef op 08 december 2003 @ 16:39:
...
Maar de standaard array uitbreiden met (generieke!) handige functies vind ik niet zo'n ramp eigenlijk :) 't is toch maar per project/page. zo kan je het String object b.v. .intValue() en .floatValue() geven. Veel kwaad kan dat imo niet.
Om het nog maar eens te zeggen: ik vind het geen ramp en het is inderdaad een zeer heldere manier om uitbreidingen toe te voegen. Maar imho blijft het een klein risico dat iemand van een voorgedefinieerde/openbare standaard uitgaat en iets anders krijgt, of dat twee mensen elkaars uitbreidingen verknoeien.

Zolang je goed documenteerd en het overzichtelijk kunt houden (ik bouw in JS vrijwel nooit serieuze projecten van honderden files of duizenden regels code dus dat moet meestal lukken) is er niets aan de hand. Ook functies die weinig/geen ruimte laten voor meerdere interpretaties (intValue etc.) moeten idd geen problemen opleveren. Wat dat betreft is het risico inderdaad vaak verwaarloosbaar klein en ook als je wel zelf iets knutselt blijft natuurlijk dat je goed moet documenteren... Wellicht ben ik gewoon ffies te conservatief in dit opzicht :)

Wel had ik op mijn vorige werk wat libraries gemaakt voor crossbrowser compatibility in de vorm van filetjes die geinclude konden worden. Daar moesten complete JS-noobs ook mee kunnen werken. Die wil ik dan niet uit moeten gaan leggen dat een "standaard"-object soms wel "standaard" is en soms "standaard-met-wat extra's" ;)

[ Voor 7% gewijzigd door Morrar op 09-12-2003 01:44 ]

Pagina: 1