Avatar billede mireigi Novice
03. juni 2008 - 14:57 Der er 25 kommentarer og
1 løsning

Problemer med arrays

Hej Eksperter,

Jeg har et kombineret ASP og JavaScript der genererer en drop down menu ud fra en tabel i en database. Tabellen indeholder 2 værdier:
Side: Id'et på den side menupunktet skal linke til.
Underside: Id'et på den der er en del af menupunktets undermenu.

Som det er nu, tilføjer jeg værdier til et array, hvor placeringen er bestemt ud fra 'Side'. Dette giver dog et problem da arrayet således ikke længere er fortløbende.

Er det muligt at definere et array i JavaScript der IKKE er fortløbende?

På forhånd tak.
Avatar billede w13 Novice
03. juni 2008 - 15:00 #1
Hvad vil du have i stedet for et fortløbende? Altså hvordan skal det se ud?
Avatar billede mireigi Novice
03. juni 2008 - 15:05 #2
Det skal være på formen:

var menus = new Array(50)

menus[1] = new Menu(var1, var2, var3, var4, ...);
menus[2] = new Menu(var1, var2, var3, var4, ...);
menus[3] = new Menu(var1, var2, var3, var4, ...);
menus[4] = new Menu(var1, var2, var3, var4, ...);
menus[5] = new Menu(var1, var2, var3, var4, ...);
menus[7] = new Menu(var1, var2, var3, var4, ...);
menus[10] = new Menu(var1, var2, var3, var4, ...);
menus[18] = new Menu(var1, var2, var3, var4, ...);
Avatar billede w13 Novice
03. juni 2008 - 15:05 #3
Og hvad har du nu? :)
Avatar billede mireigi Novice
03. juni 2008 - 15:09 #4
Jeg har det samme, men det script der genererer menustrukturen kan ikke håndtere spring mellem placeringerne i arrayet. Jeg tænker at det er nemmere at ændre arrayet til en anden form for liste/array, end at skulle ændre i 600 linjers JavaScript til generering af menustrukturen.
Avatar billede w13 Novice
03. juni 2008 - 15:13 #5
Du kan jo lave et associativt array, hvor du lægger ting i sådan her:

menus["1"] = new Menu(var1, var2, var3, var4, ...);
menus["2"] = new Menu(var1, var2, var3, var4, ...);
menus["3"] = new Menu(var1, var2, var3, var4, ...);
menus["4"] = new Menu(var1, var2, var3, var4, ...);
menus["5"] = new Menu(var1, var2, var3, var4, ...);
menus["7"] = new Menu(var1, var2, var3, var4, ...);
menus["10"] = new Menu(var1, var2, var3, var4, ...);
menus["18"] = new Menu(var1, var2, var3, var4, ...);

Så vil der ikke være tomme placeringer mellem f.eks. "7" og "10".

Det kunne også gøres med bogstaver, når det er associativt:

menus["hello"] = new Menu(var1, var2, var3, var4, ...);
menus["world"] = new Menu(var1, var2, var3, var4, ...);
...
Avatar billede w13 Novice
03. juni 2008 - 15:13 #6
Hvis du skal løbe det igennem med javascript, bør du så bare bruge en for-each-løkke.
Avatar billede mireigi Novice
03. juni 2008 - 15:21 #7
Jeg løber det ikke igennem.

Det er bygget op således at hvert menupunkt har en mouseover funktion der indeholder værdien fra 'Side' (se første post), hvor scriptet så viser den (under-)menu, den har opbygget og lagret i arrayet, ud fra den værdi funktionen får med ind.
Avatar billede w13 Novice
03. juni 2008 - 15:25 #8
Ja, men så er det vel som jeg skrev 15:13:15. =)
Avatar billede mireigi Novice
03. juni 2008 - 15:28 #9
Har lige prøvet det, og kan ikke få det til at virke.

Jeg skal ærligt indrømme at jeg ikke har 110% indsigt i scriptet, da det er en demo jeg har hentet online. Jeg har dog fundet ud af hvilke værdier jeg skal ændre for at opbygge menuen.

Hvis jeg nu smider kildekoden til de 3 filer herind, kan du så kigge på det og evt. finde en løsning, hvis der er en?
Avatar billede mireigi Novice
03. juni 2008 - 15:32 #10
Eller bedre endnu, du kan få linket jeg hentede det fra:
http://www.aspandjavascript.co.uk/javascript/drop%5Fdown%5Fmenu%5Ftutorial%5Fversion%5F2/example.zip

Det du skal ændre er i filen "One.html":
menus[7] ændres til menus[8] eller højere.
Avatar billede frand Nybegynder
03. juni 2008 - 15:33 #11
var menus = [];
menus[1] = ...;
menus[x] = ...;

arrayet vil automatisk udvidde sig. Gør det noget, at der er huller, når du alligvel ikke skal løbe igennem det?

Javascript understøtter i øvrigt ikke associative arrays.
Avatar billede w13 Novice
03. juni 2008 - 15:49 #12
mireigi>> Lige p.t. kan jeg ikke overskue at skulle regne 600 linjer kode ud og finde de rigtige steder at rette, desværre. =)
frand>> Er du sikker på det? ^o) Altså det kan godt være, at det i virkeligheden tolkes som typen object, men det burde være hip som hap i JS, da den betragter de 2 ens, eller hvad?
Avatar billede mireigi Novice
03. juni 2008 - 15:52 #13
#frand:
Jeg har prøvet det du foreslår, men det ændrer stadig ikke på noget. Menuer der ligger uden for den fortløbende arraystruktur bliver ikke vist.
Avatar billede frand Nybegynder
03. juni 2008 - 16:49 #14
Ja, det er et problem. Jeg kan se, at den navngiver menu div'erne ud fra currentMenuNo, som tæller én op for hver menu man tilføjer. Så der må ikke være huller.


http://www.hunlock.com/blogs/Mastering_Javascript_Arrays har et par ord om associative arrays
Avatar billede w13 Novice
03. juni 2008 - 18:15 #15
Ja, sim nævnt så tolkes arrays og objects ens i JS. =)
Avatar billede frand Nybegynder
03. juni 2008 - 18:26 #16
Nej. Det er to helt forskellige ting.

mitarray["hejsa"] svarer til mitarray.hejsa, du laver altså en property.

det er ikke det samme som mitarray[index]
Avatar billede roenving Novice
04. juni 2008 - 00:18 #17
Prøv at llæse oleboles artikel om den sag: http://www.eksperten.dk/artikler/227 !-)
Avatar billede w13 Novice
04. juni 2008 - 09:16 #18
Ja, det var bl.a. fra den artikel, at jeg havde mit udsagn.
F.eks. fra linjen: "I laget lige under JS-laget er den data-konstruktion, vi kalder et 'array' - og den konstruktion, vi kalder et 'object' to repræsentationer for én og samme data-konstruktion."

eller:

"Da array og object som sagt er det samme underliggende data-objekt, kan vi endda kalde med array- eller dot-notation ved både associative arrays og objects."
Avatar billede mireigi Novice
04. juni 2008 - 09:32 #19
Jeg fandt en løsning på mit problem.
Jeg gemmer to ekstra variable i databasen, hvor den ene er fortløbende og bruges til menuerne mens den anden bruges som relation mellem menuerne.

Frand og w13, hvis I smider et svar får I noget point.
Avatar billede w13 Novice
04. juni 2008 - 10:01 #20
:)
Avatar billede olebole Juniormester
04. juni 2008 - 15:58 #21
<ole>

Min artikel om arrays og objects bør opdateres. Man bør undgå konstruktionen 'associativt array' i JavaScript og i stedet anvende et object.

Det 'associative array' er i modsætning til andre sprog ikke defineret i JS, men er en uoverlagt sideeffekt af den måde, JS' egne objekter (herunder Array) er konstrueret på.

Man kan således bruge ethvert JS-objekt på samme måde:
    var o = new Date();
    o["olebole"] = "bruger";
    alert(o["olebole"]);

- eller:
    var o = new RegExp();
    o["olebole"] = "bruger";
    alert(o["olebole"]);

- eller:
    var o = new String();
    o["olebole"] = "bruger";
    alert(o["olebole"]);

- osv, osv.

Faktisk advares der i den officielle JS-reference mod at bruge Array som associativt array. I stedet rådes til brugen af Object object  =)

frand >> Du tager nu også fejl ... tingene er en anelse mere komplekse. JS' Array-objekt er internt et ganske almindeligt JS-object, der har fået 'påklistret' lidt metoder og en enkelt property. I virkeligheden er et JS-array ikke talindekseret, men strengindekseret  ;o)

Test f.eks. koden:

<script type="text/javascript">
var a = new Array("en", "to", "tre", "fire", "fem");
for (var x in a) {
    alert(x + " => " + a[x] + "\n" + (typeof x) + " :: " + (typeof a[x]))
}
</script>

/mvh
</bole>
Avatar billede olebole Juniormester
04. juni 2008 - 16:00 #22
- derfor virker denne kode også fint:

var a = new Array("en", "to", "tre");
a["3"] = "fire";

alert(a["1"]);
alert(a[3]);
Avatar billede frand Nybegynder
05. juni 2008 - 10:13 #23
Ja, vel fordi javascript genkender strengen som et tal. Ligesom alert("3"*2); viser 6.

Min pointe var bare, at i det øjeblik index ikke er et nummer, hvad enten du angiver det som en streng eller en integer, så bruger du ikke array-objektet som et "array".

var a = [];
a["hejsa"] = "en";

alert(a.length); // viser 0
Avatar billede olebole Juniormester
05. juni 2008 - 14:56 #24
"Ja, vel fordi javascript genkender strengen som et tal. Ligesom alert("3"*2); viser 6." >> Nej, det er fordi, JavaScript 'oversætter' tallet i de square brackets til en streng ved et array. Internt er array'et jo et objekt, og dér er tallet blevet ændret til en streng, så det er anvendeligt som property.

- og derfor er din pointe stadig ikke korrekt. Der kan ikke herske tvivl om, at "123" er en streng, og på trods af, at index ikke er et nummer, fungerer denne kode fint:

var a = [];
var sMyString = "123";
alert(typeof sMyString); // returnerer 'string'
a[sMyString] = "noget";
alert(a.length); // returnerer '124'

Der er således ikke tale om 'to helt forskellige ting'. Tværtimod har vi her fat i én af de ikke helt få uhensigtsmæssigheder (eller 'uigennemtænktheder'), vi trækkes med i JS.
Object objektets mangler som ideelt hashtable er et andet. Til denne opgave er Object dog stadig langt at foretrække fremfor Array - da sidstnævnte jo er en extension af Object og indeholder langt flere properties/metoder, der skal tages hensyn til i hash-sammenhænge.
At så Mozilla har valgt at 'forurene' Object objektet med en håndfuld nonstandard/proprietære properties/metoder er så en anden ting  :o|
Avatar billede frand Nybegynder
05. juni 2008 - 16:07 #25
Det er vel også det jeg siger, den kode virker fint. Men bruger du en streng, som ikke kan genkendes som et tal, så er sagen en anden.
Avatar billede olebole Juniormester
05. juni 2008 - 16:17 #26
Så er det nok dér, vi taler forbi hinanden. Jeg taler om, hvad der faktisk anvendes (en streng) - og hvordan JS bruger den ... ikke hvad strengen tilfældigvis måtte 'genkendes' som.

a = [];
a["123"] = "noget";

Her laver du en property på Array objektet. Dét er pointen!  ;o)

At alert("3"*2); viser 6 ... har helt andre årsager
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester