Baffling array problem

D

djconner

I'm a total neophyte in Javascript, trying to hack something together
fast, and run into something that I can't understand at all.

Two loops appear in sequence. The idea is that arrQuestions consists
of the answers to each of 6 questions. Each is answered by a number,
0-5, and each number can only be used once.

So arrNumbers tracks whether a particular number was used as an
answer. arrNumbers[1] would be set to 'Used' if the user answered
"one" on any question.

(All values for arrNumbers are hard-coded to 'Not Used' before this
code runs.)

Loop 1 appears to work. Then I use Loop 2 to loop through arrNumbers
and look for values that are still equal to 'Not Used'. Not only does
this loop fail to work, it actually seems to RESET the values for
arrNumbers!

Am I making some incredibly stupid newbie error here? Have I missed
some fundamental law of JavaScript like you're not allowed to nest an
IF statement within a FOR loop for some damn reason?

I freely admit that I likely don't know what I'm doing, but any and
all help would be greatly appreciated!

for(q = 0; q < 6; q++){
r = arrQuestions[q];
alert(r);
arrNumbers[r]='Used';
alert(arrNumbers[r]);
}



for(s = 0; s < 6; s++){
if(arrNumbers='Not Used'){
alert(s);
alert(arrNumbers);
ArrayOK = false;
}
}
 
B

Bill H

I'm a total neophyte in Javascript, trying to hack something together
fast, and run into something that I can't understand at all.

Two loops appear in sequence.  The idea is that arrQuestions consists
of the answers to each of 6 questions.  Each is answered by a number,
0-5, and each number can only be used once.

So arrNumbers tracks whether a particular number was used as an
answer.  arrNumbers[1] would be set to 'Used' if the user answered
"one" on any question.

(All values for arrNumbers are hard-coded to 'Not Used' before this
code runs.)

Loop 1 appears to work.  Then I use Loop 2 to loop through arrNumbers
and look for values that are still equal to 'Not Used'.  Not only does
this loop fail to work, it actually seems to RESET the values for
arrNumbers!

Am I making some incredibly stupid newbie error here?  Have I missed
some fundamental law of JavaScript like you're not allowed to nest an
IF statement within a FOR loop for some damn reason?

I freely admit that I likely don't know what I'm doing, but any and
all help would be greatly appreciated!

for(q = 0; q < 6; q++){
        r = arrQuestions[q];
        alert(r);
        arrNumbers[r]='Used';
        alert(arrNumbers[r]);

}

for(s = 0; s < 6; s++){
        if(arrNumbers='Not Used'){
        alert(s);
                alert(arrNumbers);
                ArrayOK = false;
        }



}- Hide quoted text -

- Show quoted text -


Simple error. Use == instead of = in your if statements - You are
actually setting the variable value with = . The == compares

Bill H
 
R

RobG

I'm a total neophyte in Javascript, trying to hack something together
fast, and run into something that I can't understand at all.

Two loops appear in sequence. The idea is that arrQuestions consists
of the answers to each of 6 questions. Each is answered by a number,
0-5, and each number can only be used once.

So arrNumbers tracks whether a particular number was used as an
answer. arrNumbers[1] would be set to 'Used' if the user answered
"one" on any question.

(All values for arrNumbers are hard-coded to 'Not Used' before this
code runs.)

Loop 1 appears to work. Then I use Loop 2 to loop through arrNumbers
and look for values that are still equal to 'Not Used'. Not only does
this loop fail to work, it actually seems to RESET the values for
arrNumbers!

Am I making some incredibly stupid newbie error here? Have I missed
some fundamental law of JavaScript like you're not allowed to nest an
IF statement within a FOR loop for some damn reason?

I freely admit that I likely don't know what I'm doing, but any and
all help would be greatly appreciated!

for(q = 0; q < 6; q++){

In addition to what Bill said, initialising variables without the var
keyword makes them global when the code runs. You should keep all
variables local unless you really need them to be global - that is
especially true for counters.

for (var q=0; q<6; q++) {
...
}

You might also consider using a while loop:

var q = 6;
while (q--) {
...
}

r = arrQuestions[q];
alert(r);
arrNumbers[r]='Used';
alert(arrNumbers[r]);

}

for(s = 0; s < 6; s++){
if(arrNumbers='Not Used'){
alert(s);
alert(arrNumbers);
ArrayOK = false;
}

}


A simpler way is to just set the elements of the array when the
question is answered, that way you don't have to initialise the array
with values, e.g.

var arrQuestions = []; // empty array

/* When a question is answered, if the equivalent
** array element evaluates to false (i.e. it's undefined)
*/ the question hasn't been answered so set it to true

if (arrQuestions) {
alert("Already answered");
} else {
arrQuestions = true;
alert("Marked as answered");
}
 
D

djconner

Thanks everybody, that'll teach me about PWC (Programming While
Clueless!)

A simpler way is to just set the elements of the array when the
question is answered, that way you don't have to initialise the array
with values, e.g.

Trouble in this case is that I'm modifying a Frankensteinian creation
that has ASP, HTML, Javascript and VBscript all cobbled together. For
some damned reason just about all the scripting is in VBscript (which
I'm competent with), but the validation code is in Javascript. (An
early lesson for me was that Javascript and VBscript don't play nicely
together....)
 
D

djconner

In addition to what Bill said, initialising variables without the var
keyword makes them global when the code runs. You should keep all
variables local unless you really need them to be global - that is
especially true for counters.

for (var q=0; q<6; q++) {
...
}

I initialized all the counters (with var) at the top of the function,
as I would do in VB - does that work OK?
 
T

timothytoe

I initialized all the counters (with var) at the top of the function,
as I would do in VB - does that work OK?

Yes, that is what you want to do in JavaScript.
 
R

RobG

I initialized

You mean declared. Initialising is when you declare the variable and
assign a value in one statement, e.g.

var y; // Declared variable
var x = 5; // Number primitive initialiser
var z = []; // Array initialiser

all the counters (with var) at the top of the function,
as I would do in VB - does that work OK?

Since all declarations are processed before any code is executed, you
can actually declare variables anywhere within the intended scope
(function or global). However, most seem to consider it good form to
declare them at the start of the function.

Some like to declare variables at the point they are first used. A
similar scheme is frequently used for loop counters, which are often
declared at the start of the loop, e.g.

for (var i=0, len=array.length; i<len; i--) { ... }

for (var p in obj) { ... }

var j = array.length;
while (j--) { ... }

and so on.

Some recommend against that as it might be interpreted as inferring
block scope (which javascript does not have). I like it because I can
keep track of counters more easily. Nested loops can be written:

for (var i=0, iLen=6; i<iLen; i++) {
for (var j=0, jLen=6; j<jLen; j++) {
...
}
}

so it is clear where it all belongs - but that is just my preference.
 
D

Dr J R Stockton

In comp.lang.javascript message <0e07a781-089c-45eb-8bf9-81060c19557a@v1
g2000pra.googlegroups.com>, Tue, 10 Jun 2008 13:05:12, timothytoe
Yes, that is what you want to do in JavaScript.


Not really. Variables are commonly declared at the top of their
functions. Counter variables are not commonly initialised there;
instead, they are initialised at the beginning of the loop. I presume
he did, and meant, that.

In the quoted case, that q=0 is the initialisation, independently of
whether the line contains var .


In
A = new Array(100)
S1 = 0 ; J = A.length ; while (J--) { S1 += J }
for (S2 = 0, J = A.length ; J-- ; ) { S2 += J }
X = [S1, S2]
both loops do the same additions in the same order, and they use the
same number of characters. IIRC, they are of essentially equal speed.

The S1 form is more common; but ISTM that the S2 form is clearer.
 
T

timothytoe

In comp.lang.javascript message <0e07a781-089c-45eb-8bf9-81060c19557a@v1
g2000pra.googlegroups.com>, Tue, 10 Jun 2008 13:05:12, timothytoe
<[email protected]> posted:


Yes, that is what you want to do in JavaScript.

Not really. Variables are commonly declared at the top of their
functions. Counter variables are not commonly initialised there;
instead, they are initialised at the beginning of the loop. I presume
he did, and meant, that.

In the quoted case, that q=0 is the initialisation, independently of
whether the line contains var .

In
A = new Array(100)
S1 = 0 ; J = A.length ; while (J--) { S1 += J }
for (S2 = 0, J = A.length ; J-- ; ) { S2 += J }
X = [S1, S2]
both loops do the same additions in the same order, and they use the
same number of characters. IIRC, they are of essentially equal speed.

The S1 form is more common; but ISTM that the S2 form is clearer.

--
(c) John Stockton, nr London, UK. [email protected] Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)


"Counter variables are not commonly initialised there;
instead, they are initialised at the beginning of the loop."

Commonly, perhaps. I follow Crockford's suggestion that all variables
be declared at the top of the function because of how JavaScript is
scoped. I have jslint check for this when I run my code through it. I
expect due to Crockford's book and the popularity of jslint that we'll
see more programmers moving the declaration to the top of functions.

I understand that a lot of people like to stick the "var" in the for
loop, but I see that as a habit from C that doesn't make as much sense
in JavaScript.
 
M

Michael Wojcik

timothytoe said:
I understand that a lot of people like to stick the "var" in the for
loop, but I see that as a habit from C that doesn't make as much sense
in JavaScript.

Unlikely, since that was illegal in C until C99, which is still not
widely used.

Perhaps you are thinking of C++, in which the practice of declaring
loop variables in the first clause of the "for" statement is widespread.
 
D

Dr J R Stockton

In comp.lang.javascript message <b1822aae-7615-4528-9944-c954efd20344@n1
9g2000prg.googlegroups.com>, Wed, 11 Jun 2008 16:29:09, timothytoe
"Counter variables are not commonly initialised there;
instead, they are initialised at the beginning of the loop."

Commonly, perhaps. I follow Crockford's suggestion that all variables
be declared at the top of the function because of how JavaScript is
scoped. I have jslint check for this when I run my code through it. I
expect due to Crockford's book and the popularity of jslint that we'll
see more programmers moving the declaration to the top of functions.

I understand that a lot of people like to stick the "var" in the for
loop, but I see that as a habit from C that doesn't make as much sense
in JavaScript.


Apparently you do not understand the difference between declaration
(which creates a variable) and initialisation (which gives it a value).
Declaration is done with 'var'; initialisation is done with '='.

Please read and heed newsgroup META-FAQ section 2.3.
 
T

Thomas 'PointedEars' Lahn

djconner said:
Trouble in this case is that I'm modifying a Frankensteinian creation
that has ASP, HTML, Javascript and VBscript all cobbled together.

This would appear to be the usual way to do it with ASP (server-side
VBScript, client-side J[ava]Script/ECMAScript with fallback), although I
prefer to use server-side JScript instead of server-side VBScript when
having to write for ASP.
For some damned reason just about all the scripting is in VBscript (which
I'm competent with), but the validation code is in Javascript.

The validation code would be scripting, too.
(An early lesson for me was that Javascript and VBscript don't play nicely
together....)

Whatever your problem was, it is not likely to be caused by an
incompatibility of J(ava)Script with VBScript or vice-versa. Chances are
you have been doing something else wrong.

If both J(ava)Script and VBScript are client-side, the former would have to
be JScript because VBScript is not supported by non-MSHTML user agents and
MSHTML-based UAs do not support other ECMAScript implementations than
JScript. In that case, they play nicely together as long as you observe
that they use the same namespace (which can turn to be an advantage,
consider VBScripts versatile MsgBox function for example) and that only one
of them can be the default scripting language unless you use proprietary labels.

If the J(ava)Script code is client-side and the VBScript code is server-side
(or, unlikely, vice-versa), one does not talk directly to the other because
they simply do not know of each other (there are the HTTP client and server
in between). So there is no reason to believe they would not play nicely
together.

If both J(ava)Script and VBScript are server-side in ASP, the former would
have to be JScript, too, because that is what ASP supports. It is
sufficient then to place them in separate script files and use ASP's
<@LANGUAGE@> directive to specify the used scripting language in each file.


PointedEars
 
T

Thomas 'PointedEars' Lahn

RobG said:
I initialized

You mean declared. Initialising is when you declare the variable and
assign a value in one statement, e.g.

var y; // Declared variable
var x = 5; // Number primitive initialiser
var z = []; // Array initialiser

A variable that is declared without explicit initialization is implicitly
initialized with the `undefined' value.
Since all declarations are processed before any code is executed, you
can actually declare variables anywhere within the intended scope
(function or global). However, most seem to consider it good form to
declare them at the start of the function.

*Some* do. Other developers prefer to declare them (and initialize them,
when feasible) where they are used so that they do not have to scroll up in
order to maintain their code.

Please do not present a opinion on a subject as the opinion of a supposed
majority. If the argument made in favor of an opinion is convincing, it is
enough to make it; if it is not convincing, a fallacy like this would hardly
help to support it. (Much the same goes for a supposed minority). As
Bertrand Russell put it: "There is no nonsense so arrant that it cannot be
made the creed of the vast majority by adequate government action."
[...]
Some recommend against that as it might be interpreted as inferring
block scope (which javascript does not have).

Newer versions of JavaScript[tm] support language features that facilitate
block scoping.
I like it because I can keep track of counters more easily. Nested
loops can be written:

for (var i=0, iLen=6; i<iLen; i++) {
for (var j=0, jLen=6; j<jLen; j++) {
...
}
}

so it is clear where it all belongs - but that is just my preference.

And mine.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,366
Latest member
IanCulpepp

Latest Threads

Top