Use Incoming Variable to Select Pre-Defined Array

T

Tom

I'm trying to figure out how to select one of several pre-defined
arrays based on a value passed to the function. For example:

function doRollup(Instring1) {

Array_1 = new Array (1,2,3);
Array_2 = new Array (4,5,6);
Array_3 = new Array (7,8,9);

var ArrayName = 'Array_' + Instring1;

for(x=0;x<ArrayName .length;x++)
{
// do stuff
}
}
<input type=button value="Test" onClick="doRollup(1)">

I want to be able to choose the appropriate array based on the value
of Instring1. However, in the example above, substituting variable
ArrayName for the actual array name does not work. It's merely a
string that has the same name as the array.

Any suggestions ? Thanks
 
T

Thomas 'PointedEars' Lahn

Tom said:
I'm trying to figure out how to select one of several pre-defined
arrays based on a value passed to the function. For example:

function doRollup(Instring1) {

Array_1 = new Array (1,2,3);
Array_2 = new Array (4,5,6);
Array_3 = new Array (7,8,9);

Always declare your identifiers; their scope extends to calling execution
contexts otherwise which can have rather nasty side-effects (especially in
MSHTML). Do not use identifiers starting with capital letter for anything
else but constructors and constants.

As for your problem, if you need to refer to the array by its index, make it
an element of another array:

function doRollup(instring1)
{
var a = new Array(
null,
new Array(1, 2, 3),
new Array(4, 5, 6),
new Array(7, 8, 9)
);

// ...
}

The Array constructor/factory (you can also omit the `new' here) is
supported since JavaScript 1.1, JScript 2.0, and conforming implementations
of ECMAScript Edition 1.

You can use the Array initializer since JavaScript 1.3, JScript 2.0, and
with conforming implementations of ECMAScript Edition 3:

var a = [null, [1, 2, 3], [4, 5, 6], [7, 8, 9]];

(See also: <http://PointedEars.de/es-matrix>)

I have only used the `null' first element here because you wanted the index
by which your inner Array objects can be referred, to start at 1 (one)
instead of the default 0 (zero).
var ArrayName = 'Array_' + Instring1;

In either case, then you can refer to the corresponding "inner" Array object
by

var aSelected = a[instring1];
for(x=0;x<ArrayName .length;x++)

I recommend you pick i, j, k aso. for counters and leave x, y, z aso. for
object references. Regardless, the above can be optimized (in case the
`length' property value does not change):

for (var i = 0, len = aSelected.length; i < len; i++)

Or, in reverse order, slightly faster:

for (var i = aSelected.length; i--;)

(Some have pointed out that ++i would be slightly faster than i++, but that
depends on the implementation. So I would not bother about it; write it as
you think it is understood best. You must not use --i instead of i-- here
because it is important that the value is evaluated before decremented [try
it and you'll see].)
{
// do stuff
}
}
<input type=button value="Test" onClick="doRollup(1)">

Always delimit attribute values explicitly. Write attribute names lowercase
unless required otherwise.

<input type="button" value="Test" onclick="doRollup(1)">

What about users without client-side script support?


PointedEars
 
T

Tom

Tom said:
I'm trying to figure out how to select one of several pre-defined
arrays based on a value passed to the function.  For example:
function doRollup(Instring1)  {
Array_1 = new Array (1,2,3);
Array_2 = new Array (4,5,6);
Array_3 = new Array (7,8,9);

Always declare your identifiers; their scope extends to calling execution
contexts otherwise which can have rather nasty side-effects (especially in
MSHTML).  Do not use identifiers starting with capital letter for anything
else but constructors and constants.

As for your problem, if you need to refer to the array by its index, makeit
an element of another array:

  function doRollup(instring1)
  {
    var a = new Array(
      null,
      new Array(1, 2, 3),
      new Array(4, 5, 6),
      new Array(7, 8, 9)
    );

    // ...
  }

The Array constructor/factory (you can also omit the `new' here) is
supported since JavaScript 1.1, JScript 2.0, and conforming implementations
of ECMAScript Edition 1.

You can use the Array initializer since JavaScript 1.3, JScript 2.0, and
with conforming implementations of ECMAScript Edition 3:

  var a = [null, [1, 2, 3], [4, 5, 6], [7, 8, 9]];

(See also: <http://PointedEars.de/es-matrix>)

I have only used the `null' first element here because you wanted the index
by which your inner Array objects can be referred, to start at 1 (one)
instead of the default 0 (zero).
var ArrayName = 'Array_' + Instring1;

In either case, then you can refer to the corresponding "inner" Array object
by

  var aSelected = a[instring1];
for(x=0;x<ArrayName .length;x++)

I recommend you pick i, j, k aso. for counters and leave x, y, z aso. for
object references.  Regardless, the above can be optimized (in case the
`length' property value does not change):

  for (var i = 0, len = aSelected.length; i < len; i++)

Or, in reverse order, slightly faster:

  for (var i = aSelected.length; i--;)

(Some have pointed out that ++i would be slightly faster than i++, but that
depends on the implementation.  So I would not bother about it; write it as
you think it is understood best.  You must not use --i instead of i-- here
because it is important that the value is evaluated before decremented [try
it and you'll see].)
   {
    // do stuff
   }
}
<input type=button value="Test" onClick="doRollup(1)">

Always delimit attribute values explicitly.  Write attribute names lowercase
unless required otherwise.

  <input type="button" value="Test" onclick="doRollup(1)">

What about users without client-side script support?

PointedEars

Thanks for the help. After posting my original question I had an idea
to do an array of array names and I was able to make that work using
the convention window[ArrayNameList[instring1]]. I like your
suggestion of the array of arrays. That's cleaner than the
ArrayNameList method. Thanks again.
 
L

Logos

Thanks for the help.  After posting my original question I had an idea
to do an array of array names and I was able to make that work using
the convention window[ArrayNameList[instring1]].  I like your
suggestion of the array of arrays.  That's cleaner than the
ArrayNameList method.  Thanks again.

As I'm sure others will point out, you probably shouldn't be using an
Array as a hash. One usually uses an Object for this instead.

(eg)
var Arrays =new Object();
Arrays["some string"] =[1,2,3];
Arrays["some other string"] =[4,5,6];
....

Of course, you can always combine all these into a single statement as
well. My favourite way to do a hash like this is to use an object
literal (mostly because I use JSON a lot, so for me it's easy to read
and write them):

var Arrays ={"someString":[0,1,2], "anotherString":[3,4,5]};

If you wanted to get SUPER fancy, you could do this:

var myArray ={"someString":[0,1,2], "anotherString":[3,4,5]}
[Instring1];
 
T

Thomas 'PointedEars' Lahn

Logos said:
Thanks for the help.  After posting my original question I had an idea
to do an array of array names and I was able to make that work using
the convention window[ArrayNameList[instring1]].  I like your
suggestion of the array of arrays.  That's cleaner than the
ArrayNameList method.  Thanks again.

As I'm sure others will point out, you probably shouldn't be using an
Array as a hash.

And he didn't. Besides, there are no hashes, you mean property names. What
really matters is that `window' should not be used when the Global Object
is meant instead.
One usually uses an Object for this instead.

(eg)
var Arrays =new Object();

A variable identifier of `Arrays' is unwise at best.
Arrays["some string"] =[1,2,3];
Arrays["some other string"] =[4,5,6];

AIUI, that is _not_ what his solution would have done:

var ArrayNameList = [null, "Array_1", "Array_2", "Array_3"];

Mind you that `instring1' was a *number* despite the identifier. However,
this would only work if Array_1 aso. were names of properties of `window',
or the Global Object as the Variable/Activation Object of the global
execution context is the Global Object.
...

Of course, you can always combine all these into a single statement as
well. My favourite way to do a hash

Maybe an object can be called a hash *table*. Maybe. However, using
terminology from other programming languages can be quite confusing.


PointedEars
 
L

Logos

And he didn't.  Besides, there are no hashes, you mean property names.  What
really matters is that `window' should not be used when the Global Object
is meant instead.

A hash by any other name would smell as sweet! :grin: Functionally
speaking, in this instance they are the same. If had explicitly said
that instring1 from ArrayNameList[Instring1] was always going to be a
numeric value, I wouldn't argue. However I can easily see someone
deciding that the value of instring1 should be made to be easier to
read and therefore a string - especially when the variable name has
the word string in it!
A variable identifier of `Arrays' is unwise at best.

In production code, to be sure. This, however, was an example with
the variable name chosen for clarity.
Maybe an object can be called a hash *table*.  Maybe.  However, using
terminology from other programming languages can be quite confusing.

You're correct on that score. I shouldn't assume a level of knowledge
that may not be there for basic programming concepts, especially for a
scripting language.

My solution dealt with my interpretation of the actual problem he was
having with his sample code. To me he seemed to be saying that he
wanted to assign an array to a variable based on the value of the
function parameter. (ie, he was trying to concatenate the parameter
value to a strong so as to access the array with the same name). In
my experience, a (maybe!) hash table indexed to the function parameter
would be the best solution, and so I proposed that.
 
T

Thomas 'PointedEars' Lahn

Logos said:
A hash by any other name would smell as sweet! :grin: Functionally
speaking, in this instance they are the same.

No. For example, with Array objects it matters whether the property name
can be interpreted as an unsigned integer; if yes, the `length' property
value is modified accordingly. In fact, using non-numeric properties with
Array objects is in most cases inappropriate (an exception is a collection
implementation) and potentially harmful (the Array object inherits
properties from Array.prototype that could be overridden or overwritten
this way); an Object object should be used instead then. But even with an
Object object (as you suggested) one has to take care that one does not
overwrite or override built-in properties. AFAIK that is rather different
from hashes (Perl) or dictionaries (Python).
If had explicitly said that instring1 from ArrayNameList[Instring1] was
always going to be a numeric value, I wouldn't argue.

It would be a property name nevertheless. All property names are (stored
as) strings, and converted to string on access if not already a string.
However I can easily see someone deciding that the value of instring1
should be made to be easier to read and therefore a string - especially
when the variable name has the word string in it!

You are jumping to conclusions. The OP mentioned nothing of the sort.
The argument identifier might simply have been chosen unwisely by them.
In production code, to be sure. This, however, was an example with
the variable name chosen for clarity.

Examples should promote good code style (as expected in production code),
not a bad one.
You're correct on that score. I shouldn't assume a level of knowledge
that may not be there for basic programming concepts, especially for a
scripting language.

Pot, kettle, black. It is *you* who doesn't know what they are talking
about.


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
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top