Trying to create an array?

  • Thread starter The Natural Philosopher
  • Start date
T

The Natural Philosopher

I am trying to create what amounts to an array of 'structures'.

I.e. I want to dynamically add to and access an object as

myobject[number].anothernumber // actually represents a nesting level.

and

myobject[number].elementintheDOM // this is a pointer to
//store particular elements..i.e.
//I want to be able to do things like

myobject[number].elementintheDOM.style.display='block';

Myobject is essentially external to the (one) function that accesses it
- or a static, in C terms within it. 'number' is not a continuous
set..its a sparse matrix.


Now I have searched the net, and there seems to be no one who has
actually done this.

All the idiots guides are for more simple arrays. And most seem to be
giving what amounts to the same examples.


What I need is the correct syntax for declaring it, adding to it, and
stepping through it to extract values. So easy in a strict type
language, so non intuitive in javascript..

Mind you, i never managed to create an array of pointers to functions in
C either. If I got the syntax right, the compiler choked :)

So easy in Assembler..;-)
 
S

slebetman

From your description of a desired API:

I am trying to create what amounts to an array of 'structures'.
<snip>
myobject[number].elementintheDOM
<snip>
myobject[number].elementintheDOM.style.display='block';

And this requirement:
'number' is not a continuous
set..its a sparse matrix.

I'd say what you want is javascript objects, not arrays. Just get
comfortable with the object syntax:

var myobject = {}; /*declares an empty object*/
var myarray = []; /*declares an empty array, for completeness sake*/

myobject[10]; /*attribute '10' doesn't exist
so this will return 'undefined'*/

myobject[10] = {}; /*assign an empty object to attribute 10*/

/*now that we have an empty object, we can assign to it*/

myobject[10][1] = 'hello';

/*note that keys doesn't need to be numbers*/

myobject['foo'] = ['this','is','an','array'];

/*and as you know if the key is a simple non reserved string
you can access using . syntax*/

myobject.foo[3]; /*get the word 'array' form the array*/

/*which also works for assignment:*/

myobject.bat = {
type : 'mammal',
locomotion : 'flight'
}

myobject.bat.type; /*is a 'mammal'*/

/*oh, and that up there is the literal
notation for javascript objects, which is where the
J ava-
S cript
O bject
N otation
protocol comes from*/

/*so, how do you iterate through the object? Use for..in:*/

for (var n in myobject) {
doSomethingWith(myobject[n]);
}

/*so, to wrap things up, you want something like the following:*/

var myobject = {};
myobject[1] = {};
myobject[1].elementintheDOM = document.getElementById('someDivId');
myobject[1].elementintheDOM.style.display='block';

//lets do for all elements in the object:
function setDisplayBlock (obj) {
for (var n in obj) {
//check if element is defined first:
if (obj[n].elementintheDOM) {
/*Of course, you really should do more checks here
for example, obj[n] itself may be undefined or null
or obj[n] may mistakenly store a number or string
instead of an object.
*/
obj[n].elementintheDOM.style.display='block';
}
}
}

setDisplayBlock(myobject);
 
T

The Natural Philosopher

Conrad said:
Sparse arrays are usually handled with linked lists. JS doesn't provide
built-in support for linked lists, but they be implemented quite easily.
The problem is that you want to use linked-list functionality ("stepping
through it to extract values"), but also insist on having numeric
indices on the list. Usually you'd go from one node in the list to the
next (or previous), passing a reference node as an argument. If you
don't provide a reference node, the list methods would have to search up
and down to adjust the 'next' and 'prev' properties of the neighboring
nodes. It's possible, but not very efficient if your indices are far apart.

Since you're more experienced in low-level languages, why not tell us
what you're trying to do? There may be a better way in a high-level
language like JS.


Um, use Assembler then?

My browser doesn't support it.
Anyway I found a fragment that was close enough for me to guess my way
through.

For interests sake,here is the code..that works.
**********************************************
<script type="text/javascript" language="JavaScript">
var mymenu =new Array() // array for our menus.

function Mentry(lev,obj)

// this was the breakthrough. Object not struct..
{
this.lev=lev;
this.obj=obj;
}
function expand (level,ourparent)
// expands a menu at this level with this parent id.
// Kills all menus at this level or below as well
{
var allmenus;
var exp=/L/;
// look for divs with Id set to LXXPYYY
//where XX is the level, and yyy is the parent id
var i;
var idstring;
level=Number(level);
ourparent=Number(ourparent);
// this registers a div layer that has been switched on..
// the reason is to make IE7 faster with a lot of
// DOM to search through. This way it only
// searches the whole DOM once. when a layer is enabled
if(!(mymenu[ourparent])) // not yet registered
{
allmenus=document.getElementsByTagName('DIV'); // get all the divs
for (i=0; i<allmenus.length;i++)
{
var sample=allmenus;
if (exp.test(sample.id)) // Its a LEVEL div, which we want..
{
if (Number(sample.id.slice(1,3))==level+1)
{
if (Number(sample.id.slice(4))==Number(ourparent))
{
mymenu[ourparent]=new Mentry();
// second breakhrough. Have to create element
// as cant reserve mem. Presumablye 'array' has imlicit?
mymenu[ourparent].lev=level+1;
mymenu[ourparent].obj=sample;
}
}
}
}
}
document.getElementById("glass").style.display='block';
// and lay the drip tray for mouse droppings underneath..
for (i in mymenu) // skip through registered layers
{
// kill any layers at my level or below..except me.
if(mymenu.lev>level) //needs zapping?
{
if(i==ourparent) // that's us
mymenu.obj.style.display='block';
else mymenu.obj.style.display='none';
}
}
}
// called on mouse over the 'mouse dropping' glass layer
// (transparent overlay of everything under the flyouts)
function contract() // simply clears all except level 0 menus
{
expand(0,0); // kill all submenus
document.getElementById("glass").style.display='none';
}

*********************

As I said the reason was to speed up IE7 screen updates, which on an
oldish machine were abysmally slow. I reasoned that searching through
every DIV in the DOM to find the ones that I needed to flip was simply
too much like hard work for it, and the other alternative, working out
at the php stage the ID of *every* layer that needed toggling when I
moused over one of several thousand possible little divs would make a
large page even larger. The matrix of the switchable layers (actually
much smaller than the number of trigger points on the document) can be
scanned pretty fast.

In use its quite amusing as the first mouseover menu event is slow, but
as it 'learns' the map it speeds up immensely.

If I could be bothered, i'd precompute the matrix at php time, but this
is good enough, and I have more important things to do.
 
T

The Natural Philosopher

Conrad said:
(in good weather)

I thought you needed a way to "step through" the mymenu array from one
element to the next? If you don't, mymenu should probably be an Object,
not an Array.

I do when looking fo stuff to turn off.
I'm sure that can be optimized; any machine that can run IE7 should be
able to handle a simple menu script.

There are in excess of a thousand divs in the menu contaner..
You don't have to search through every div, and you only have to find
your targets once. You could probably improve performance by only
looking at the divs in the menu container. So instead of

document.getElementsByTagName("DIV")

you can write

menucontainer.getElementsByTagName("DIV")

That's a neat thought, which I will remember for future use.. but 99% of
the dives are already in that container.
I don't see a matrix in the posted code sample, just a one-dimensional
array.

Well its a none dmensionl aray of one dimesnional objects= 2 dimensions ;-)

You can do the calculations at window.onload, or in a script at the
bottom of the page, which would avoid the delay at the first mouseover.

Yeah..or at php time as well. So precompute the values.
A couple of other suggestions:
var mymenu = new Array();

If you don't know the final length of the array, you could use an array
literal:

var mymenu = [];

Ok. thanx.
Since JS is weakly typed, it's usually not necessary to explicitly cast
values. Even if you did need it, "level = +level" would be preferred.
OK.
Thanx again.
It's a div that has an "L" somewhere in its ID. Might be a menu node,
might be the "bottomLayer". You can check the ID and extract the numbers
at the same time:

I could. but i made sure the only divs with L are the ones I want..

var matches = sample.id.match(/^L(\d\d)P(\d{3})$/);
mymenu[ourparent]=new Mentry();
// second breakhrough. Have to create element
// as cant reserve mem. Presumablye 'array' has imlicit?
mymenu[ourparent].lev=level+1;
mymenu[ourparent].obj=sample;

I don't understand that comment. You can't manage memory directly with
JS, and you can add elements anywhere in an array. That part could be
written in a more compact way:

mymenu[ourparent] = new Mentry(level + 1, sample);

Yup. No what I meant was that to my 'C' brain, there is no implicit
reservation of memory, or explicit 'malloc()' needed to build a mem
block top hold a structure. Instead 'new object' means 'do a malloc like
thing, and represent it in this form'..as I said,OOP is not my native land..
This is what is confusing me. I can declare an array that is implicitly
extensible without having to say 'new' every time I add an element, but
I can't declare and array of objects that is implicitly extensible..i
have to declare and opbject, and make a new one and tag it onto my
implicitly extensible array..


If performance is an issue, you'll want to avoid unnecessary calls to
the DOM. Get the "glass" element at the top of your code, and use a
reference to it in the functions.

yeah, could do. You mean find it once, and store that?

That's not the proper way to iterate over an array; use for(..;..;..).
If you do want to iterate like that, skipping the empty elements, why
not use an object instead of an array in the first place?

Cos I don't know enough..

that's why i am asking..
 

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