How to optimize this JavaScript?

O

Oltmans

Hello all,

I'm dealing with <table> and <tr>s here and I've a function that takes
two arguments, one is the array of strings(containing <tr> ids e.g. if
we have <tr id="hello"> then our string array might contain 'hello'---
please hold on , let me explain a bit and I'm sure it will make some
sense) and other argument is the table id, which in my case is
"myTable". Now in this function I've to loop through all TRs (rows) in
this table and find those TRs whose value matches with IDs contained
in our other argument i.e. array of strings containing IDs). Here is
how my function looks like
------------------------------------------------------------------------------------

function findRows(idStringArray, tableID)
{

var
rows=document.getElementById("myTable").getElementByTagsName("tr");
var table=document.getElementById("myTable");

for (var i=0; i<idStringArray.length; i++)
{
for (var j=0; j<rows.length;j++)

{
if ( rows[j].ID == idStringArray )
//Got the row, can now do anything with it. So we have to
store all such rows
//whose ID matches with any of the ID given in
idStringArray
}
}


}


Now problem is that I've huge number rows in a table and the above
code is taking too much time. My code above is taking some time and I
need to optimize this. Any ideas on how should I optimize this code?
Please enlighten me, I will appreciate your feedback.

Thanks,
Oltmans
 
S

shimmyshack

Hello all,

I'm dealing with <table> and <tr>s here and I've a function that takes
two arguments, one is the array of strings(containing <tr> ids e.g. if
we have <tr id="hello"> then our string array might contain 'hello'---
please hold on , let me explain a bit and I'm sure it will make some
sense) and other argument is the table id, which in my case is
"myTable". Now in this function I've to loop through all TRs (rows) in
this table and find those TRs whose value matches with IDs contained
in our other argument i.e. array of strings containing IDs). Here is
how my function looks like
------------------------------------------------------------------------------------

function findRows(idStringArray, tableID)
{

var
rows=document.getElementById("myTable").getElementByTagsName("tr");
var table=document.getElementById("myTable");

for (var i=0; i<idStringArray.length; i++)
{
for (var j=0; j<rows.length;j++)

{
if ( rows[j].ID == idStringArray )
//Got the row, can now do anything with it. So we have to
store all such rows
//whose ID matches with any of the ID given in
idStringArray
}
}

}

Now problem is that I've huge number rows in a table and the above
code is taking too much time. My code above is taking some time and I
need to optimize this. Any ideas on how should I optimize this code?
Please enlighten me, I will appreciate your feedback.

Thanks,
Oltmans


why are you doing this at one time up front? are you sure you _need_
to do this and not do it dynamically on mouse over, or use some other
method of putting those values into an array in javascript (i assume
they are being generated dynamically) one little thing that wont make
a lot of difference is dont calculate the length of an array each time
you loop around, but the answer is to not do this kind of thing at all
unless you absolutely have to.
 
T

Thomas 'PointedEars' Lahn

Oltmans said:
I'm dealing with <table> and <tr>s here and I've a function that takes
two arguments, one is the array of strings(containing <tr> ids e.g. if
we have <tr id="hello"> then our string array might contain 'hello'---
[...]) and other argument is the table id, which in my case is
"myTable". Now in this function I've to loop through all TRs (rows) in
this table and find those TRs whose value matches with IDs contained
in our other argument i.e. array of strings containing IDs).

You should simply check whether or not an element with such an ID exists.
Since IDs have to be unique throughout a document, there can't be another
element with the same ID. See the bottom of my posting.
Here is how my function looks like
------------------------------------------------------------------------------------

function findRows(idStringArray, tableID)
{

var
rows=document.getElementById("myTable").getElementByTagsName("tr");

Won't work. The method name is *getElementsByTagName*. Also,
HTMLTableElement objects have a `row' property to yield a NodeList
of all its first-ancestor HTMLTableRowElement objects.
var table=document.getElementById("myTable");

It would make more sense if that line was before the former, so that `table'
could be used there instead of `document.getElementById("myTable")'.

var table;
if ((table = document.getElementById("myTable")))
{
for (var rows = table.rows, i = rows && rows.length; i--;)
{
// ...
}
}
for (var i=0; i<idStringArray.length; i++)

Generally, when iteration order is not important

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

is faster than the above.
{
for (var j=0; j<rows.length;j++)

for (var j = rows.length; j--;)
{
if ( rows[j].ID == idStringArray )


Won't work. The property name is *id*. ECMAScript implementations are
case-sensitive.
//Got the row, can now do anything with it. So we have to
store all such rows
//whose ID matches with any of the ID given in
idStringArray
}
}
}

Now problem is that I've huge number rows in a table and the above
code is taking too much time. [...] I need to optimize this.
Any ideas on how should I optimize this code?
Please enlighten me, I will appreciate your feedback.

for (var i = idStringArray.length; i--;)
{
var tr;
if ((tr = document.getElementById(idStringArray))
{
// Got the row, can now do anything with it.
}
}


HTH

PointedEars
 
E

Evertjan.

Oltmans wrote on 23 sep 2007 in comp.lang.javascript:
Hello all,

I'm dealing with <table> and <tr>s here and I've a function

Please do not multipost on usenet.

Crosspost if you must.
 
W

waqas.younas

Hello Thomas,

Many thanks for your reply. I must say that I'm impressed with your
skills & knowledge about JavaScript. I've a question about your
suggestion

1)- Why do we have this " i=rows && rows.length " in following loop, I
can't really figure that out. I'm guessing that by using such an
initialization in for loop 'i' will be assigned to rows.length on
every iteration , where rows.length is a constant.
for (var rows = table.rows, i = rows && rows.length; i--;)

I'm wondering why this " for (var rows=table.rows,i=rows.length;i--) "
won't work ?

2)-I'm quite amazed by your understanding of the subject. I'm a newbie
to JavaScript so what books or websites would you recommend? My focus
is to learn both the core JavaScript language and Clientside scripting
as well.

Thanks and I look forward to hearing from you.

Thanks,
Oltmans

Oltmans said:
I'm dealing with <table> and <tr>s here and I've a function that takes
two arguments, one is the array of strings(containing <tr> ids e.g. if
we have <tr id="hello"> then our string array might contain 'hello'---
[...]) and other argument is the table id, which in my case is
"myTable". Now in this function I've to loop through all TRs (rows) in
this table and find those TRs whose value matches with IDs contained
in our other argument i.e. array of strings containing IDs).

You should simply check whether or not an element with such an ID exists.
Since IDs have to be unique throughout a document, there can't be another
element with the same ID. See the bottom of my posting.
Here is how my function looks like
------------------------------------------------------------------------------------

function findRows(idStringArray, tableID)
{

var
rows=document.getElementById("myTable").getElementByTagsName("tr");

Won't work. The method name is *getElementsByTagName*. Also,
HTMLTableElement objects have a `row' property to yield a NodeList
of all its first-ancestor HTMLTableRowElement objects.
var table=document.getElementById("myTable");

It would make more sense if that line was before the former, so that `table'
could be used there instead of `document.getElementById("myTable")'.

var table;
if ((table = document.getElementById("myTable")))
{
for (var rows = table.rows, i = rows && rows.length; i--;)
{
// ...
}
}
for (var i=0; i<idStringArray.length; i++)

Generally, when iteration order is not important

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

is faster than the above.
{
for (var j=0; j<rows.length;j++)

for (var j = rows.length; j--;)
{
if ( rows[j].ID == idStringArray )


Won't work. The property name is *id*. ECMAScript implementations are
case-sensitive.
//Got the row, can now do anything with it. So we have to
store all such rows
//whose ID matches with any of the ID given in
idStringArray
}
}
}

Now problem is that I've huge number rows in a table and the above
code is taking too much time. [...] I need to optimize this.
Any ideas on how should I optimize this code?
Please enlighten me, I will appreciate your feedback.

for (var i = idStringArray.length; i--;)
{
var tr;
if ((tr = document.getElementById(idStringArray))
{
// Got the row, can now do anything with it.
}
}


HTH

PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
 
O

Oltmans

Hello Thomas,

Many thanks for your reply. I must say that I'm impressed with your
skills & knowledge about JavaScript. I've a question about your
suggestion

1)- Why do we have this " i=rows && rows.length " in following loop, I
can't really figure that out. I'm guessing that by using such an
initialization in for loop 'i' will be assigned to rows.length on
every iteration , where rows.length is a constant.
for (var rows = table.rows, i = rows && rows.length; i--;)

I'm wondering why this " for (var rows=table.rows,i=rows.length;i--) "
won't work ?

2)-I'm quite amazed by your understanding of the subject. I'm a newbie
to JavaScript so what books or websites would you recommend? My focus
is to learn both the core JavaScript language and Clientside scripting
as well.

Thanks and I look forward to hearing from you.

Thanks,
Oltmans

Oltmans said:
I'm dealing with <table> and <tr>s here and I've a function that takes
two arguments, one is the array of strings(containing <tr> ids e.g. if
we have <tr id="hello"> then our string array might contain 'hello'---
[...]) and other argument is the table id, which in my case is
"myTable". Now in this function I've to loop through all TRs (rows) in
this table and find those TRs whose value matches with IDs contained
in our other argument i.e. array of strings containing IDs).

You should simply check whether or not an element with such an ID exists.
Since IDs have to be unique throughout a document, there can't be another
element with the same ID. See the bottom of my posting.
Here is how my function looks like
------------------------------------------------------------------------------------
function findRows(idStringArray, tableID)
{
var
rows=document.getElementById("myTable").getElementByTagsName("tr");

Won't work. The method name is *getElementsByTagName*. Also,
HTMLTableElement objects have a `row' property to yield a NodeList
of all its first-ancestor HTMLTableRowElement objects.
var table=document.getElementById("myTable");

It would make more sense if that line was before the former, so that `table'
could be used there instead of `document.getElementById("myTable")'.

var table;
if ((table = document.getElementById("myTable")))
{
for (var rows = table.rows, i = rows && rows.length; i--;)
{
// ...
}
}
for (var i=0; i<idStringArray.length; i++)

Generally, when iteration order is not important

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

is faster than the above.
{
for (var j=0; j<rows.length;j++)

for (var j = rows.length; j--;)


{
if ( rows[j].ID == idStringArray )


Won't work. The property name is *id*. ECMAScript implementations are
case-sensitive.
//Got the row, can now do anything with it. So we have to
store all such rows
//whose ID matches with any of the ID given in
idStringArray
}
}
}
Now problem is that I've huge number rows in a table and the above
code is taking too much time. [...] I need to optimize this.
Any ideas on how should I optimize this code?
Please enlighten me, I will appreciate your feedback.

for (var i = idStringArray.length; i--;)
{
var tr;
if ((tr = document.getElementById(idStringArray))
{
// Got the row, can now do anything with it.
}
}

HTH

PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
 
O

Oltmans

Oltmans wrote on 23 sep 2007 in comp.lang.javascript:



Please do not multipost on usenet.

Crosspost if you must.


I'm sorry about that. I'm using Google groups, so I'm not sure what is
crossposting? I guess if I'm sending a message to comp.lang.javascript
and Cc it to another group then this qualifies to be called as a
crosspost. I guess I'm making some sense here, right?
 
E

Evertjan.

Oltmans wrote on 24 sep 2007 in comp.lang.javascript:
I'm sorry about that. I'm using Google groups,

don't! [use g-g]
so I'm not sure what is
crossposting? I guess if I'm sending a message to comp.lang.javascript
and Cc it to another group then this qualifies to be called as a
crosspost. I guess I'm making some sense here, right?

Cc is something with email, I believe, usenet is not email.

Get a decent news reader, they are free.
And start reading up on usenet. Google search will help you.
 
T

Thomas 'PointedEars' Lahn

Oltmans said:
Many thanks for your reply. I must say that I'm impressed with your
skills & knowledge about JavaScript.

Thank you.
[...]
1)- Why do we have this " i=rows && rows.length " in following loop, I
can't really figure that out. I'm guessing that by using such an
initialization in for loop 'i' will be assigned to rows.length on
every iteration , where rows.length is a constant.

Watch for the difference between commas and semicolons in the code. `i' is
only initialized once, and rows.length is not a constant (it's value is
considered to not change though, so such a loop is not suited if one deletes
or adds rows within the loop).

What happens instead is this:

`rows' has been initialized before with the value that read access to
`table.rows' yields. However, it may be that the DOM object representing
the table does not have a `rows' property (because the DOM of the user agent
[UA] does not implement W3C DOM Level 2 HTML interfaces, or implements them
incompletely or incorrectly). In that case, it is likely that read access
would yield a false-value (probably `undefined').

Now,

i = rows && rows.length;

evaluates the Boolean expression first (`&&' has precedence over `='), as in

i = (rows && rows.length);

Since there is only one `&&' (logical AND) operation, this means the second
(latter) operand is only evaluated if the first (former) operand evaluates
(type-converts) to `true'.

Meaning that if `rows' yields `undefined' (because `table.rows' yielded
`undefined') or another false-value, `rows.length' is not evaluated, and
`i' is assigned `undefined' (or whatever value `table.rows' yielded).

As `undefined' is type-converted to `false', the operation `i--' is
evaluated to `false', too (postfix decrement); the loop condition is not met
in the first place, and the associated block statement is not executed at all.

If instead `rows' yields a true-value (a reference to a NodeList object as
specified in W3C DOM Level 2 HTML), `i' is assigned `rows.length' and the
loop is only executed if that yields a value greater than 0.

In the latter case, in each loop `i' is first evaluated and type-converted
to Boolean. As long as it is greater than 0, it is type-converted to `true'
and the associated block statement is executed after `i' was decremented.
As it becomes `0', it is type-converted to `false', and after `i' is
decremented again, the loop stops.
^
I'm wondering why this " for (var rows=table.rows,i=rows.length;i--) " ^
won't work ?

Because the `for' statement requires three parameters (initialization, run
condition, post-loop operation), and you have only provided two of them:
the `;' after the run-condition part is mandatory, and it is missing in your
code.
2)-I'm quite amazed by your understanding of the subject. I'm a newbie
to JavaScript so what books or websites would you recommend? My focus
is to learn both the core JavaScript language and Clientside scripting
as well.

I can not recommend any book, because I had never a need for that for
learning any programming language; online material, including newsgroups
sufficed to date. Due to the number of bad examples posted out of known
books here, including the book recommended in the FAQ (which is considered
by some to be just the best of the bad books), I would instead recommend
*against* any books about the subjects discussed here (which not only
include the programming language, but also several interfaces, like DOMs).
Either they are hopelessly outdated, factually wrong, propose unwise
practices, or a combination of those.

As you subscribe to this newsgroup and read the postings here (especially
the more elaborate ones), I daresay you will learn much more than you could
from any book. Maybe not always in such a step-by-step way as in this
posting, but I am pretty sure you'll manage.
[top post]

Please don't do that again.

http://jibbering.com/faq/

That also contains links to references and tutorials.


HTH

PointedEars
 
O

Oltmans

Thanks a lot, Thomas. I really appreciate your time and effort. Thanks
again.

--Oltmans

Oltmans said:
Many thanks for your reply. I must say that I'm impressed with your
skills & knowledge about JavaScript.

Thank you.
[...]
1)- Why do we have this " i=rows && rows.length " in following loop, I
can't really figure that out. I'm guessing that by using such an
initialization in for loop 'i' will be assigned to rows.length on
every iteration , where rows.length is a constant.

Watch for the difference between commas and semicolons in the code. `i' is
only initialized once, and rows.length is not a constant (it's value is
considered to not change though, so such a loop is not suited if one deletes
or adds rows within the loop).

What happens instead is this:

`rows' has been initialized before with the value that read access to
`table.rows' yields. However, it may be that the DOM object representing
the table does not have a `rows' property (because the DOM of the user agent
[UA] does not implement W3C DOM Level 2 HTML interfaces, or implements them
incompletely or incorrectly). In that case, it is likely that read access
would yield a false-value (probably `undefined').

Now,

i = rows && rows.length;

evaluates the Boolean expression first (`&&' has precedence over `='), as in

i = (rows && rows.length);

Since there is only one `&&' (logical AND) operation, this means the second
(latter) operand is only evaluated if the first (former) operand evaluates
(type-converts) to `true'.

Meaning that if `rows' yields `undefined' (because `table.rows' yielded
`undefined') or another false-value, `rows.length' is not evaluated, and
`i' is assigned `undefined' (or whatever value `table.rows' yielded).

As `undefined' is type-converted to `false', the operation `i--' is
evaluated to `false', too (postfix decrement); the loop condition is not met
in the first place, and the associated block statement is not executed at all.

If instead `rows' yields a true-value (a reference to a NodeList object as
specified in W3C DOM Level 2 HTML), `i' is assigned `rows.length' and the
loop is only executed if that yields a value greater than 0.

In the latter case, in each loop `i' is first evaluated and type-converted
to Boolean. As long as it is greater than 0, it is type-converted to `true'
and the associated block statement is executed after `i' was decremented.
As it becomes `0', it is type-converted to `false', and after `i' is
decremented again, the loop stops.

^> I'm wondering why this " for (var rows=table.rows,i=rows.length;i--) "

^
won't work ?

Because the `for' statement requires three parameters (initialization, run
condition, post-loop operation), and you have only provided two of them:
the `;' after the run-condition part is mandatory, and it is missing in your
code.
2)-I'm quite amazed by your understanding of the subject. I'm a newbie
to JavaScript so what books or websites would you recommend? My focus
is to learn both the core JavaScript language and Clientside scripting
as well.

I can not recommend any book, because I had never a need for that for
learning any programming language; online material, including newsgroups
sufficed to date. Due to the number of bad examples posted out of known
books here, including the book recommended in the FAQ (which is considered
by some to be just the best of the bad books), I would instead recommend
*against* any books about the subjects discussed here (which not only
include the programming language, but also several interfaces, like DOMs).
Either they are hopelessly outdated, factually wrong, propose unwise
practices, or a combination of those.

As you subscribe to this newsgroup and read the postings here (especially
the more elaborate ones), I daresay you will learn much more than you could
from any book. Maybe not always in such a step-by-step way as in this
posting, but I am pretty sure you'll manage.
[top post]

Please don't do that again.

http://jibbering.com/faq/

That also contains links to references and tutorials.

HTH

PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <[email protected]>
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top