/    Sign up×
Community /Pin to ProfileBookmark

Recursive function is (possibly) writing over array?

Hello,

Here’s a simplified version of the function that’s giving me trouble:

[CODE]
function saveArray(w){
var arr=”[‘z’,[“;
var wc=w.childNodes; //get childNodes as array
for (n=0;n<wc.length;n++){ //for each of the childNodes
if (wc[n].type && wc[n].type==’checkbox’){ //if it’s a checkbox
if (arr!=”[‘z’,[“){arr+=”,”;} //add a comma to separate the arrays
arr+=”[‘a’,’b’,’c’,’d’]”; //add array
}else if (wc[n].tagName==’DIV’){ //if it’s a div
if (arr!=”[‘z’,[“){arr+=”,”;} //add a comma to separate the arrays
arr+=saveArray(wc[n]); //add array for div
}
}
arr+=”]]”;
return arr;
}

document.getElementById(‘test’).innerHTML=saveArray(<some div>);
[/CODE]

If the structure looks something like this:

[CODE]
<DIV id=’a’>
<input type=’checkbox’ id=’cb_1′>
<input type=’checkbox’ id=’cb_2′>

<DIV id=’b’>
<input type=’checkbox’ id=’cb_3′>
<input type=’checkbox’ id=’cb_4′>
</DIV>

<input type=’checkbox’ id=’cb_5′>
<input type=’checkbox’ id=’cb_6′>
</DIV>[/CODE]

, the output string stops after cb_4 and does not finish the rest of the checkboxes.

The goal of what I’m trying to accomplish is take the given structure that’s on a page and transform the values i’m interested in into an array to store in a db or use later on. If anyone knows why this is or can think of a better way of doing this, I’m all ears!

Thanks for your suggestions.

to post a comment
JavaScript

5 Comments(s)

Copy linkTweet thisAlerts:
@KorSep 16.2010 — <i>
</i>var wc=w.childNodes; //get childNodes as array

Well, the childNodes are different, according to the div. For div id='a', the childNodes are the two first inputs, the div in the middle and the last 2 inputs, [I]but not the 2 inputs inside the middle div[/I]. Don't mention that FF will count the possible textNodes as well as being childNodes.

Moreover, your result is not an array, it is a string.

how do expect your final result (the string) to look like?
Copy linkTweet thisAlerts:
@speghettiCodeauthorSep 16.2010 — Hello,

Thank you for your reply.

I understand childNodes only provides direct children of the parent element. I think I'm ok with that.

I also think it's ok to include text nodes in the array since the "if" statements are there to ensure an action is taken only if there's a checkbox or another DIV found. Would you agree?

I would hope the end result would be an array or something I could eval() into an array. For the given example, something like the following would be a good start:

[CODE]
['z',[
['a','b','c','d'],
['a','b','c','d'],
['z',[
['a','b','c','d'],
['a','b','c','d']
]
],
['a','b','c','d'],
['a','b','c','d']
]
[/CODE]


I've been working at this for 3 days (embarassingly enough) and have played with versions which try to create arrays and "push" the data as needed, but it does exactly the same thing whether using arrays or text as above.

Here's an attempt using arrays:

[CODE]
function arrayFromContainer(c){
var arr=new Array();
var l=childNodesThatCount(c);//returns just the DIV and checkboxes as an array

for (n=(l.length-1);n>=0;n--){
alert(l[n].id||'?');
if (l[n].type && l[n].type=='checkbox'){
var arr_cb=arrayFromCheck(l[n]);//assigns an array of values to arr_cb
arr.push(arr_cb);
}
else if (l[n].tagName=='DIV' && l[n].id.substr(0,4)=='supe'){
var arr_sc=arrayFromSupContainer(l[n]); //assigns array of arrays to arr_sc
arr.push(arr_sc);
}
}
return arr;
}
[/CODE]


This code, using the previous example, returns
[CODE]
['z',[
['z',[
[
['a','b','c','d'],
['a','b','c','d']
]
]
]
]
]
[/CODE]


Could it be that I'm passing arrays by reference and not by values? How could I pass the values? The above example drills down in the the child nodes but only populates the information for the first DIV it comes across in those child nodes.

If you have a better idea of how to extract the data while keeping the parent/child relationships, I'm open to suggestions.

Thank you for your help.
Copy linkTweet thisAlerts:
@speghettiCodeauthorSep 16.2010 — Anybody spending the time to read this deserves the answer:

in the "for loop", n must be kept private and replaced with: var n

now it works.
Copy linkTweet thisAlerts:
@KorSep 16.2010 — Anybody spending the time to read this deserves the answer:

in the "for loop", n must be kept private and replaced with: var n

now it works.[/QUOTE]

We would have never guessed that you have another global variable called [B]n[/B] in some other code :rolleyes: Yes, the good old rule is safe: use as few global variable as possible and only when it is absolutely necessary. Define the Globals clearly, always outside the functions. Give them intricate names, not "i", "n"... ?
Copy linkTweet thisAlerts:
@speghettiCodeauthorSep 16.2010 — It's probably a good idea to try to guess outrageous things when I post. Who knows what I've declared and where! ?

Thanks for your suggestions.
×

Success!

Help @speghettiCode spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 6.2,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @meenaratha,
tipped: article
amount: 1000 SATS,

tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,
)...