By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,905 Members | 879 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,905 IT Pros & Developers. It's quick & easy.

Sort array question

P: n/a
Hi, I'm using the following code to retrieve data from an xml file and
populate a javascript array. The data is then displayed in html table
form. I would like to then be able to sort by each column. Once the
array elements are split, what is the best way to sort them? Thank you.

//populate data object with data from xml file.
//Data is a comma delimited list of values
var jsData = new Array();
jsData[0] = {lib: "#field SUBLOOKUP_LIB#",doc: "#field SUBLOOKUP_DOC#",
com: "#field SUBLOOKUP_COM"};

//split up values for each element
var o = jsData[0];
o.lib = o.lib.split(",");
o.doc = o.doc.split(",");
o.com = o.com.split(",");

Nov 23 '05 #1
Share this Question
Share on Google+
21 Replies


P: n/a
ye*****@yahoo.com wrote:
[...] I would like to then be able to sort by each column. Once the
array elements are split, what is the best way to sort them? [...]

//populate data object with data from xml file.
//Data is a comma delimited list of values
var jsData = new Array();
jsData[0] = {lib: "#field SUBLOOKUP_LIB#",doc: "#field SUBLOOKUP_DOC#",
com: "#field SUBLOOKUP_COM"};

//split up values for each element
var o = jsData[0];
o.lib = o.lib.split(",");
o.doc = o.doc.split(",");
o.com = o.com.split(",");


Since the table implies a dependency of all data in one row, it
does not make sense to sort each column array independently.

You need a different data structure, then you can apply a comparator:

// make each row an object as element of an array.
var a = [];
for (var i = 0, len = o.lib.length; i < len; i++)
{
a.push({lib: o.lib[i], doc: o.doc[i], com: o.com[i]});
}

// comparator
function sortByLibAsc(a, b)
{
if (a && b)
{
if (a.lib < b.lib)
{
return -1;
}
else if (a.lib > b.lib)
{
return 1;
}
}

return 0;
}

a.sort(sortByLib);
PointedEars
Nov 23 '05 #2

P: n/a
Thomas 'PointedEars' Lahn wrote:
// comparator
function sortByLibAsc(a, b)
{
[...]
}

a.sort(sortByLib);


a.sort(sortByLibAsc);

of course.
PointedEars
Nov 23 '05 #3

P: n/a
thank you for the help Pointed, I'm getting closer.

How can I get my data to look like this...

jsData[0] = {lib:"string1",doc:"01",com:"blah"};
jsData[1] = {lib:"string2",doc:"02",com:"blah"};
jsData[2] = {lib:"string3",doc:"03",com:"blah"};
jsData[3] = {lib:"string4",doc:"04",com:"blah"};
jsData[4] = {lib:"string5",doc:"05",com:"blah"};
jsData[5] = {lib:"string6",doc:"06",com:"blah"};
jsData[6] = {lib:"string7",doc:"07",com:"blah"};

....from my data object that looks like this?

//this is how I extract the data, but I need it to be in the above
format
var jsData = new Array();
jsData[0] = {lib: "#field SUBLOOKUP_LIB#",doc: "#field SUBLOOKUP_DOC#",
com: "#field SUBLOOKUP_COM"};

var o = jsData[0];
o.lib = o.lib.split(",");
o.doc = o.doc.split(",");
o.com = o.com.split(",");

Thanks.

Nov 23 '05 #4

P: n/a
ye*****@yahoo.com wrote:
thank you for the help Pointed, I'm getting closer.
However, you should read and adhere to <http://jibbering.com/faq/#FAQ2_3>,
especially <http://www.jibbering.com/faq/faq_notes/clj_posts.html>, if you
desire my further help.
How can I get my data to look like this...

jsData[0] = {lib:"string1",doc:"01",com:"blah"};
jsData[1] = {lib:"string2",doc:"02",com:"blah"};
jsData[2] = {lib:"string3",doc:"03",com:"blah"};
jsData[3] = {lib:"string4",doc:"04",com:"blah"};
jsData[4] = {lib:"string5",doc:"05",com:"blah"};
jsData[5] = {lib:"string6",doc:"06",com:"blah"};
jsData[6] = {lib:"string7",doc:"07",com:"blah"};

...from my data object that looks like this?

//this is how I extract the data, but I need it to be in the above
format
var jsData = new Array();
jsData[0] = {lib: "#field SUBLOOKUP_LIB#",doc: "#field SUBLOOKUP_DOC#",
com: "#field SUBLOOKUP_COM"};

var o = jsData[0];
o.lib = o.lib.split(",");
o.doc = o.doc.split(",");
o.com = o.com.split(",");


This will do nothing (well OK, it will create array objects with one
element). There is no way the data below can be transformed into the
data above. As I wrote before, you need to post _real_ input and
output data if one is to find a viable transformation algorithm.
PointedEars
Nov 23 '05 #5

P: n/a
> However, you should read and adhere to <http://jibbering.com/faq/#FAQ2_3>,
especially <http://www.jibbering.com/faq/faq_notes/clj_posts.html>, if you
desire my further help.
thanks for the hot tip!
As I wrote before, you need to post _real_ input and
output data if one is to find a viable transformation algorithm.


is this sufficient? This is as real as I can give you.

sadData[0] =
{lib:"string1,string2,string3,string4",doc:"01,02, 03,04",com:"blah,blah,blah,blah"};
and this is the format I would like to change it to:

happyData[0] = {lib:"string1",doc:"01",com:"blah"};
happyData[1] = {lib:"string2",doc:"02",com:"blah"};
happyData[2] = {lib:"string3",doc:"03",com:"blah"};
happyData[3] = {lib:"string4",doc:"04",com:"blah"};

Nov 23 '05 #6

P: n/a
ye*****@yahoo.com wrote:
However, you should read and adhere to <http://jibbering.com/faq/#FAQ2_3>,
especially <http://www.jibbering.com/faq/faq_notes/clj_posts.html>, if you
desire my further help.


thanks for the hot tip!
As I wrote before, you need to post _real_ input and
output data if one is to find a viable transformation algorithm.


is this sufficient? This is as real as I can give you.

sadData[0] =
{lib:"string1,string2,string3,string4",doc:"01,02, 03,04",com:"blah,blah,blah,blah"};
and this is the format I would like to change it to:

happyData[0] = {lib:"string1",doc:"01",com:"blah"};
happyData[1] = {lib:"string2",doc:"02",com:"blah"};
happyData[2] = {lib:"string3",doc:"03",com:"blah"};
happyData[3] = {lib:"string4",doc:"04",com:"blah"};


This will do the re-format, but not sort. I think Thomas' first post
will do that (but I haven't tried it). The original sadData array is
not modified, property names and values are stored in temporary arrays
is for convenience (shorter names, shallower access).
<script type="text/javascript">

var sadData = [
{
lib:"string1,string2,string3,string4",
doc:"01,02,03,04",
com:"blah,blah,blah,blah"
}
];

function processData(obj)
{
var prop; // Temp storage for property name
var oProps = []; // Store names of obj properties
var oVals = []; // Store values as arrays
var tArray = []; // Processed data

// Store property names & values converted to arrays
for ( prop in obj ){
oVals[oVals.length] = obj[prop].split(',');
oProps[oProps.length] = prop;
}

// Load property names & values into tArray
for (var i=0, m=oVals[0].length; i<m; ++i ){
tArray[i] = {};

for (var j=0, n=oProps.length; j<n; ++j){
tArray[i][oProps[j]] = oVals[j][i];
}
}
return tArray;
}

/* What the result should look like
happyData[0] = {lib:"string1",doc:"01",com:"blah"};
happyData[1] = {lib:"string2",doc:"02",com:"blah"};
happyData[2] = {lib:"string3",doc:"03",com:"blah"};
happyData[3] = {lib:"string4",doc:"04",com:"blah"};
*/

function showObjData(obj)
{
var c, t = [];
var prop;
for (var i=0, m=obj.length; i<m; ++i){
t[i] = 'obj[' + i + '] = {';
c = 0;
for (prop in obj[i]){
if (c++ != 0) t[i] += ',';
t[i] += prop + ':"' + obj[i][prop] + '"';
}
t[i] += '}';
}
alert(t.join('\n'));
}

var happyData = processData(sadData[0]);
showObjData(happyData);

</script>

--
Rob
Nov 23 '05 #7

P: n/a
>This will do the re-format, but not sort. I think Thomas' first post
will do that (but I haven't tried it). The original sadData array is
not modified, property names and values are stored in temporary arrays
is for convenience (shorter names, shallower access).


Excellent. Thank you Rob. I will implement this tomorrow and see if it
solves my problem.

Nov 23 '05 #8

P: n/a
ye*****@yahoo.com wrote:
^^^^^^^^^^^^^^^^^^^^^^^^
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
However, you should read and adhere to
<http://jibbering.com/faq/#FAQ2_3>, especially
<http://www.jibbering.com/faq/faq_notes/clj_posts.html>, if you desire my
further help.
thanks for the hot tip!


OK, I have to be blunt: Please provide proper attribution
as you can see in postings of other people in this thread.
As I wrote before, you need to post _real_ input and
output data if one is to find a viable transformation algorithm.


is this sufficient? This is as real as I can give you.

sadData[0] =

{lib:"string1,string2,string3,string4",doc:"01,02, 03,04",com:"blah,blah,blah,blah"};

and this is the format I would like to change it to:

happyData[0] = {lib:"string1",doc:"01",com:"blah"};
happyData[1] = {lib:"string2",doc:"02",com:"blah"};
happyData[2] = {lib:"string3",doc:"03",com:"blah"};
happyData[3] = {lib:"string4",doc:"04",com:"blah"};


While Rob's approach seems viable, I find it too complicated and
inefficient. My advice for the time being is to perform both the
transformations I described in <news:25****************@PointedEars.de>
and <news:15****************@PointedEars.de> one after another.
As for the first transformation, you do not need to overwrite your
original data:

var o = sadData[0];
var mediumData = {};
mediumData.lib = o.lib.split(",");
mediumData.id = o.id.split(",");
mediumData.com = o.com.split(",");

Then transform `mediumData' into `happyData' as described, and
apply any comparator you would like on `happyData'.
HTH

PointedEars
Nov 23 '05 #9

P: n/a
RobG wrote:
This will do the re-format, but not sort. I think Thomas' first post
will do that (but I haven't tried it).
It will. Test it with `string5' instead of `string1', for example.
I re-included the comparator and its application here for convenience.
The original sadData array is not modified,
Same here.
property names and values are stored in temporary arrays is for
convenience (shorter names, shallower access).
What do you mean by "shallower access" here?
<script type="text/javascript">

var sadData = [
{
lib:"string1,string2,string3,string4",
doc:"01,02,03,04",
com:"blah,blah,blah,blah"
}
];

function processData(obj)
{
var prop; // Temp storage for property name
var oProps = []; // Store names of obj properties
var oVals = []; // Store values as arrays
var tArray = []; // Processed data

// Store property names & values converted to arrays
for ( prop in obj ){
oVals[oVals.length] = obj[prop].split(',');
oProps[oProps.length] = prop;
}
Iterating through the object properties more than one time is probably
faster than saving them in an array first and then iterate through that
array.
// Load property names & values into tArray
for (var i=0, m=oVals[0].length; i<m; ++i ){
tArray[i] = {};

for (var j=0, n=oProps.length; j<n; ++j){
tArray[i][oProps[j]] = oVals[j][i];
}
}
return tArray;
}

[...]
function showObjData(obj)
{
var c, t = [];
var prop;
for (var i=0, m=obj.length; i<m; ++i){
t[i] = 'obj[' + i + '] = {';
c = 0;
for (prop in obj[i]){
if (c++ != 0) t[i] += ',';
t[i] += prop + ':"' + obj[i][prop] + '"';
}
t[i] += '}';
}
alert(t.join('\n'));
}

var happyData = processData(sadData[0]);
showObjData(happyData);

</script>


As I said in <news:17****************@PointedEars.de> and as you
recognized, two transformations are necessary here. However, it
is still possible to increase efficiency and universality.

Compare:

var
sadData = [
{lib: "string1,string2,string3,string4",
doc: "01,02,03,04",
com: "blah,blah,blah,blah"}
],
o = sadData[0],
p,
mediumData = {},
maxLen = 0,
len;

for (p in o)
// this implies no order of properties; if order is important,
// one has to set up an appropriate algorithm, perhaps one using
// ["property1", "property2", "property3"]
{
mediumData[p] = o[p].split(",");

if (maxLen < (len = mediumData[p].length))
{
maxLen = len;
}
}

// formatted output
Object.prototype.toString = function()
{
var a = [];
a.push("\n{");
for (var p in this)
{
a.push(p, " = ", this[p], "\n");
}
a.push("}\n");
return a.join("");
}

// debugging
alert(mediumData);

var happyData = [];
for (var i = 0; i < maxLen; i++)
// or (var i = maxLen; i--;) since it's sorted later anyway.
{
happyData[i] = {};

for (p in o)
{
happyData[i][p] = mediumData[p][i];
}
}

// debugging
alert(happyData);

// comparator
function sortByLibAsc(a, b)
{
if (a && b)
{
if (a.lib < b.lib)
{
return -1;
}
else if (a.lib > b.lib)
{
return 1;
}
}

return 0;
}

// apply the comparator
happyData.sort(sortByLibAsc);

// debugging
alert(happyData);
Regards,
PointedEars
Nov 23 '05 #10

P: n/a
Thomas 'PointedEars' Lahn wrote:
RobG wrote:
This will do the re-format, but not sort. I think Thomas' first post
will do that (but I haven't tried it).
It will. Test it with `string5' instead of `string1', for example.
I re-included the comparator and its application here for convenience.
The original sadData array is not modified,


Same here.
property names and values are stored in temporary arrays is for
convenience (shorter names, shallower access).


What do you mean by "shallower access" here?


I meant using references lower down the the scope chain to reduce the
length of lookups (I think I only cut down one level anyway). Compare
with your:

o = sadData[0],
[...]
// Store property names & values converted to arrays
for ( prop in obj ){
oVals[oVals.length] = obj[prop].split(',');
oProps[oProps.length] = prop;
}


Iterating through the object properties more than one time is probably
faster than saving them in an array first and then iterate through that
array.


I think the two approaches are very similar - you store the values in a
single object that is a modified copy of the original (mediumData with
the values changed to arrays), I've used an intermediate step of
separate arrays for property names and values that are then used to
build the new object.

I like the elegance of your approach, I originally did it the same way
but was modifying the original object - I wanted to change that and used
arrays out of habit I suppose.
[...]
As I said in <news:17****************@PointedEars.de> and as you
For some reason I can't locate messages in Thunderbird using the message
ID. I'm sure it used to do it... there's a 'find message by id'
extension for the Mozilla news reader, maybe I'll change to that.
[...] for (p in o)
// this implies no order of properties; if order is important,
// one has to set up an appropriate algorithm, perhaps one using
// ["property1", "property2", "property3"]
{
mediumData[p] = o[p].split(",");

if (maxLen < (len = mediumData[p].length))
{
maxLen = len;
}
}


An issue for the OP to address is what to do if there are a different
number of values in each comma-separated 'record' - should empty
elements be inserted? Is that allowed to occur? It seems to me the
original data structure is deficient, the relationship between items is
their position in the array rather than some explicit link (though that
would mean a bigger data structure).

[...]

You solution is great, I've yet to fully understand the pros/cons of
adding functions to prototypes, building objects or keeping them as
plain functions so tend to stick to the latter.

--
Rob
Nov 23 '05 #11

P: n/a
VK

ye*****@yahoo.com wrote:
Hi, I'm using the following code to retrieve data from an xml file and
populate a javascript array. The data is then displayed in html table
form. I would like to then be able to sort by each column. Once the
array elements are split, what is the best way to sort them? Thank you.

//populate data object with data from xml file.
//Data is a comma delimited list of values
var jsData = new Array();
jsData[0] = {lib: "#field SUBLOOKUP_LIB#",doc: "#field SUBLOOKUP_DOC#",
com: "#field SUBLOOKUP_COM"};

//split up values for each element
var o = jsData[0];
o.lib = o.lib.split(",");
o.doc = o.doc.split(",");
o.com = o.com.split(",");


As you may notice your data table stays under 90 degrees angle against
the needed position (thus records are going vertically).

So the first thing you need to pivot your table

[0]
// retrieve data - your orginal code:
sadData =
{lib:"string1,string2,string3,string4",
doc:"01,02,03,04",
com:"blah1,blah2,blah3,blah4"};

var tmp = [];
tmp[0] = sadData.lib.split(',');
tmp[1] = sadData.doc.split(',');
tmp[2] = sadData.com.split(',');

[1]
// pivot table:
var arr = [];
for (i=0; i<tmp[0].length; i++) {
arr[i] = [tmp[0][i],tmp[1][i],tmp[2][i]];
}

[2]
// JavaScript array is not really multidimensional -
// it's so called "jagged array" - a single dimension array
// having other arrays as its elements. Besides other
// interesting things it also means that you can apply
// sort() method right on the top dimension w/o
// ant additional transformations:

function sortByStringDown(a,b) {
var i = sortByStringDown.args;
if (b[i] < a[i]) {return -1;}
else if (b[i] > a[i]) {return 1;}
else {return 0;}
}

sortByStringDown.args = 0;
// This will sort recods by the first field in descending order:
arr.sort(sortByStringDown);

Nov 23 '05 #12

P: n/a
RobG wrote:
Thomas 'PointedEars' Lahn wrote:
RobG wrote:
[snipped because of "ACK :)"]
As I said in <news:17****************@PointedEars.de> and as you
For some reason I can't locate messages in Thunderbird using the message
ID. I'm sure it used to do it... there's a 'find message by id'
extension for the Mozilla news reader, maybe I'll change to that.


The Message-ID Finder extension is probably provided along with your
installer version of SeaMonkey. It is also available for Thunderbird
and works fine in my v1.0.7/Linux (although I seldom need it) :)

<http://messageidfinder.mozdev.org/>
[...]
for (p in o)
// this implies no order of properties; if order is important,
// one has to set up an appropriate algorithm, perhaps one using
// ["property1", "property2", "property3"]
{
mediumData[p] = o[p].split(",");

if (maxLen < (len = mediumData[p].length))
{
maxLen = len;
}
}
An issue for the OP to address is what to do if there are a different
number of values in each comma-separated 'record' - should empty
elements be inserted? Is that allowed to occur?


`empty' is not precise. It turns out that if a value is omitted, how
it ends up in the transformed data depends on how it was omitted:

a) ",foo,bar" => ""; "foo"; "bar"
"foo,,bar" => "foo"; ""; "bar"
"foo,bar," => "foo"; "bar"; ""

b) "foo,bar" if other property strings have more than two values
=> "foo"; "bar"; undefined

"foo,bar" if other property strings have no more than two values
=> "foo"; "bar"

(read `"foo,bar"' as

[{property1: "foo,bar", property2: ..., ...}]

and `"foo"; "bar"' as

[{property1: "foo", property2: ..., ...},
{property1: "bar", property2: ..., ...},
...] )

That is why I introduced the `maxLen' variable. The maximum number of
comma-separated elements per property determines the number of "rows"
(i.e. the array length) in the transformed data.
It seems to me the original data structure is deficient, the relationship
between items is their position in the array rather than some explicit
link (though that would mean a bigger data structure).
ACK
[...]
You solution is great, I've yet to fully understand the pros/cons of
adding functions to prototypes, building objects or keeping them as
plain functions so tend to stick to the latter.


Thank you :) In case of any questions, do not hesitate to ask.
\V/ PointedEars
Nov 23 '05 #13

P: n/a
VK wrote:
So the first thing you need to pivot your table
[...]


Nice solution (a little bit inefficient, though).
However, the OP needed an Object object, not an array.
PointedEars
Nov 23 '05 #14

P: n/a
VK

Thomas 'PointedEars' Lahn wrote:
VK wrote:
So the first thing you need to pivot your table
[...]


Nice solution (a little bit inefficient, though).
However, the OP needed an Object object, not an array.


As I'm reading the OP he needed to sort *array* of records. As I stated
before by staying withing the array only (w/o array<>hashtable
transformations) we are saving precious millis for the whole process.
I know that it is only bacause of the broken implementation on every
each JavaScript enabled computer (because Object and Array are really
the same). But if the implentation is guaranteed to be broken of every
single platform - why do not exploit it?

;-))

Nov 23 '05 #15

P: n/a
VK said the following on 11/18/2005 5:35 AM:
Thomas 'PointedEars' Lahn wrote:
VK wrote:

So the first thing you need to pivot your table
[...]
Nice solution (a little bit inefficient, though).
However, the OP needed an Object object, not an array.

As I'm reading the OP he needed to sort *array* of records.


He may have thought he needed to sort arrays but sometimes a better
solution involves using some other mechanism than what is originally though.

As I stated before by staying withing the array only (w/o array<>hashtable
transformations) we are saving precious millis for the whole process.
What does this have to do with array<>hashtables?
I know that it is only bacause of the broken implementation on every
each JavaScript enabled computer (because Object and Array are really
the same).
Huh? Arrays and Objects are *not* the same thing. We keep telling you
that and you keep ignoring it.
But if the implentation is guaranteed to be broken of every
single platform - why do not exploit it?


Nothing is guaranteed on the Web. Especially not Browser Behavior.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Nov 23 '05 #16

P: n/a
VK wrote:
Thomas 'PointedEars' Lahn wrote:
VK wrote:
> So the first thing you need to pivot your table
> [...]
Nice solution (a little bit inefficient, though).
However, the OP needed an Object object, not an array.


As I'm reading the OP he needed to sort *array* of records. [...]


No, his array `jsData' has (perhaps misguidedly) only one element,
`jsData[0]'. The basic original data is that element, an (extended)
Object object where he first wanted to split each property's string
value into an array (I helped him with that in another thread, see
<URL:news:25****************@PointedEars.de>),
but in fact he wanted them to be arranged so that they can be sorted
easily by a named criterion.

He has clarified input and expected output format for the transformation
in <URL:news:11**********************@g14g2000cwa.goo glegroups.com>,
long enough (ca. 31 standard hours) before your followup.

And finally, both RobG and me already found an appropriate solution
in <URL:news:MB*************@news.optus.net.au> et seqq. and
<URL:news:17****************@PointedEars.de>, ca. 30 standard hours
and ca. 23 standard hours before your followup.

That is not at all to say your posting was irrelevant or in some other
way a Bad Thing, however it did not address the OPs expectations. Since
this is a newsgroup and not a support forum, that is fine with me. But
you should at least acknowledge it.
[misconceptions]


As always recommended, you should get informed _before_ you post.
HTH & HAND

PointedEars
Nov 23 '05 #17

P: n/a
VK

Randy Webb wrote:
He may have thought he needed to sort arrays but sometimes a better
solution involves using some other mechanism than what is originally though.
Mmm... Sorting is possible only on objects supporting IComparable
interface. Such are *for example* Array or String.
Object object doesn't have IComparable interface so a sentence like
"you need objects to sort" is meaningless to my *humble* mind.
Huh? Arrays and Objects are *not* the same thing. We keep telling you
that and you keep ignoring it.


Do you care for one more attempt? Because this topic was discussed
here:
<http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/039e84717c0978d9/188f8dd6f2af8fe7?hl=en#188f8dd6f2af8fe7>

and I got nothing but explanations how stupid am I and that the Object
or Array performance are the same. After that actually I had to conduct
my own research for the best performance. Results are posted here.

Actually skip on explanations - I'm too tired of this crap. Other code
is based on the proper understanding of Object and Array nature, my
code is based on a broken implementation exploit which is not
guaranteed to be presented everywhere.
OP is free to choose whatever he wants.
But if the implentation is guaranteed to be broken of every
single platform - why do not exploit it?


Nothing is guaranteed on the Web. Especially not Browser Behavior.


True. Let me re-phrase it: it is guaranteed on those 5 browsers I do
anyhow care of.

Nov 23 '05 #18

P: n/a
VK wrote:
Randy Webb wrote:
He may have thought he needed to sort arrays but sometimes a better
solution involves using some other mechanism than what is originally
though.
Mmm... Sorting is possible only on objects supporting IComparable
interface. Such are *for example* Array or String. Object object
doesn't have IComparable interface


I beg your pardon? This is J(ava)Script/ECMAScript, _not_ Java. There
is no IComparable interface, apart from the W3C DOM interfaces (which
are not part of the language) there are _no_ interfaces at all. The
relevant Object and Array specifications can be found in ECMAScript
Edition 3 Final, not in the Sun Java (2) Platform API Specification.
so a sentence like "you need objects to sort" is meaningless to my
*humble* mind.
Where is that sentence? Right, it is nowhere, you invented it from
what you understood was meant. Again.
Huh? Arrays and Objects are *not* the same thing. We keep telling you
that and you keep ignoring it.


Do you care for one more attempt? Because this topic was discussed
here:

<http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/039e84717c0978d9/188f8dd6f2af8fe7?hl=en#188f8dd6f2af8fe7>
and I got nothing but explanations how stupid am I
To include one of my favorite quotes: "Stupid is as stupid does."

You stated boldly several times in this thread something that could
be easily dismissed as nonsense due to hard fact, without being able
to provide any hard evidence that backed up your statement or your
argument. Again.

However, as I recall, nobody called you stupid or implied that you are.
I, for one, called your _argument_ nonsense because it was, from a very
objective point of view (for example you referred to CDATA in terms of
JS core string values). Lasse, Richard and I tried (and obviously
failed) to explain to you that your whole argument is based on several
basic misconceptions, such as that the ECMAScript specification did not
matter. As you insisted you be right anyway and dismissed all provided
evidence out of hand, the tone got a little bit darker.
and that the Object or Array performance are the same.


They probably are. This has nothing to do with performance, it has to do
with data structure.

Object objects are objects. Array objects are objects. However, Array
objects (i.e. objects derived from the built-in Array object) provide more
features than Object objects (i.e. objects derived from the built-in Object
object) and handle the creation of properties in a slightly different way
(so that certain numbered properties become array elements, as Lasse
explained). That is why you will have a hard time sorting object
properties of a single Object object and will have not sorting array
elements of a single Array object.

However, this thread was about how to sort Object objects that are elements
of an array _within that array_ regarding a criterion which happened to be
the value of a common property of those Object objects.
> But if the implentation is guaranteed to be broken of every
> single platform - why do not exploit it?

Nothing is guaranteed on the Web. Especially not Browser Behavior.


True. Let me re-phrase it: it is guaranteed on those 5 browsers I do
anyhow care of.


Name the browsers you are talking of (with unforged User-Agent header
value) and the behavior you consider broken regarding what you think
is relevant to this thread.
PointedEars
Nov 23 '05 #19

P: n/a
Thomas 'PointedEars' Lahn wrote:
RobG wrote:

Thomas 'PointedEars' Lahn wrote:
RobG wrote:
[snipped because of "ACK :)"]
As I said in <news:17****************@PointedEars.de> and as you


For some reason I can't locate messages in Thunderbird using the message
ID. I'm sure it used to do it... there's a 'find message by id'
extension for the Mozilla news reader, maybe I'll change to that.

The Message-ID Finder extension is probably provided along with your
installer version of SeaMonkey. It is also available for Thunderbird
and works fine in my v1.0.7/Linux (although I seldom need it) :)

<http://messageidfinder.mozdev.org/>

[...]

Installed the Thunderbird extension - works like a charm. Thanks!
--
Rob
Nov 23 '05 #20

P: n/a
VK wrote:
Randy Webb wrote:
He may have thought he needed to sort arrays but sometimes a
better solution involves using some other mechanism than what
is originally though.
Mmm... Sorting is possible only on objects supporting IComparable
interface. Such are *for example* Array or String.
Object object doesn't have IComparable interface so a sentence
like "you need objects to sort" is meaningless to my *humble*
mind.
Huh? Arrays and Objects are *not* the same thing. We keep
telling you that and you keep ignoring it.


Do you care for one more attempt? Because this topic was
discussed here:
<http://groups.google.com/group/comp....pt/browse_frm/
thread/039e84717c0978d9/188f8dd6f2af8fe7?hl=en#188f8dd6f2af8fe7>

and I got nothing but explanations how stupid am I and that
the Object or Array performance are the same.


That is not what was said, though given your record for misunderstanding
any explanations given to you I cannot be surprised by more evidence
that you do not (or will not) understand what is explained to you. It is
that seemingly wilful disregard for the efforts of others to improve
your understanding that is (IMO inevitably) turning the nature of the
responses you receive to your posts towards the exclusively negative.
After that actually I had to conduct my own research for the
best performance. Results are posted here.
You mean on this group? In the thread referenced about the most you said
on the subject was:-

<quote cite="news:11**********************@g49g2000cwa.go oglegroups.com"
Pre-declared Array object served with proper integer index values
gives me 6 sec time gain on my %windir%\temp\ directory (hundreds
of files and folders) in comparison with Hashtable and 3 sec over
mis-treated Array (used one time as hash, another time as array).
You may imagine what is even 3 sec for usability issue. To keep
this time gain though I have to stay with Array w/o temporary
transformations Array > Hash > Array.
</quote>

- by which you appear to mean that using - anArray[integer] - gave
you a 6 second performance gain over using - anObject[string] - and
a 3 second gain over using - anArray[string].
Actually skip on explanations -
Yet again, assertions without anything to support them, or allow others
to directly discredit them.
I'm too tired of this crap.
Answer the questions you are asked and you may see the resolution of the
subject.
Other code is based on the proper understanding of Object and
Array nature, my code is based on a broken implementation exploit
which is not guaranteed to be presented everywhere.
OP is free to choose whatever he wants.


In the past you have posted examples of you attempts to time javascript,
and demonstrated your rational in drawing conclusions form those tests.
And at the time it was pointed out that the individual tests included so
much beyond what you were making statements about, and differed in what
they included beyond the subject of you conclusions, that any
conclusions drawn from the results would be invalid. The testing
methodology you demonstrated was so poor as to be useless, invalidating
you conclusions as a consequence.

As you have reacted to the criticism of you methodology by refusing to
post any more examples of your testing methods it is impossible to judge
whether thy have changed, but it seems reasonable to conclude that they
have not and so any deductions you now assert are backed by unshown
tests must reasonably be dismissed as based on fundamentally flawed
data. You can only change that impression by demonstrating that you
methodology has improved; by posting the code that does demonstrate the
points you are trying to make.

Consider the problem we have here: The question is which formulation of
property accessor most rapidly resolves into the value of interest. We
don't actually need to attempt to work out how fast any particular
property accessor is, only their relative performance. So given, for
example, the following two functions:-

function compA(a, b){
var x = a[1];
var y = b[1];
return (x < y) - (x > y);
}
function compB(a, b){
var x = a['1'];
var y = b['1'];
return (x < y) - (x > y);
}

- the only difference between them is that one uses an integer to access
the properties of an object and the other uses a string. Apart from that
they are identical. Theoretically any overheads in executing one will be
identical to the overheads in executing the other (given the same
arguments) and the _difference_ between their performance should be
entirely attributable to the use of the different types of property
accessor.

Having narrowed the subject of the test down to just the feature of
interest it may be possible to draw conclusions about subject, all else
being equal. Unfortunately all else is not equal, for one thing we
cannot perform the test without the influence of background tasks on
multitasking operating systems. But still, lets give it a whirl and see
what happens.

The functions above are comparison functions for use with the
Array.prototype.sort method, as it is sorting arrays that is of interest
here. We will use them to sort arrays of objects and arrays of arrays,
where the objects being sorted have two named properties including the
one being referenced and the arrays have two elements (so the look-up
performance should not be that influenced by the size of the objects in
use). The pertinent property will be assigned a random number and the
random numbers in the objects in each array to be sorted will be in the
same order so that each array will be sorted in exactly the same way.
The number of calls to the comparison functions will be counted (which
will verify that all of the arrays are undergoing the same sorting
process) and the array will have 10000 elements so that the process
takes long enough to minimise the influence of the low resolution of
timers available to javascript. All of the difference measurements are
against a dot-notation property accessor accessing a named property. The
test page is:-

<html>
<head>
<title></title>
<script type="text/javascript">
var a1 = [];
var a2 = [];
var a3 = [];
var a4 = [];
var a5 = [];
var y = [];
var i = 10000;

for(var c = 0;c < i;++c){
y.push(Math.random());
}

for(var c = 0;c < i;++c){
a1.push({'0':'x','1':y[c]});
a2.push(a1[c]);
a3.push(['x', y[c]]);
a4.push(a3[c]);
a5.push({'0':'x',n:y[c]});
}

function compA(a, b){
var x = a[1];
var y = b[1];
++count;
return (x < y) - (x > y);
}
function compB(a, b){
var x = a['1'];
var y = b['1'];
++count;
return (x < y) - (x > y);
}
function compC(a, b){
var x = a.n;
var y = b.n;
++count;
return (x < y) - (x > y);
}
</script>
</head>
<body>
<script type="text/javascript">
var start, end, dur, base;
var count = 0;

document.write('<br>Array of '+i+' objects using obj.n:-<br>');
start = new Date().getTime();
c = a5.sort(compC);
end = new Date().getTime();
base = dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;

document.write('<br>Array of '+i+' arrays using ar[\'1\']:-<br>');
start = new Date().getTime();
c = a4.sort(compB);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;

document.write('<br>Array of '+i+' arrays using ar[1]:-<br>');
start = new Date().getTime();
c = a3.sort(compA);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;

document.write('<br>Array of '+i+' objects using obj[\'1\']:-<br>');
start = new Date().getTime();
c = a2.sort(compB);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
count = 0;

document.write('<br>Array of '+i+' objects using obj[1]:-<br>');
start = new Date().getTime();
c = a1.sort(compA);
end = new Date().getTime();
dur = (end - start);
document.write('Duration:- '+dur+'ms<br>');
document.write('Comparisons performed:- '+count+'<br>');
document.write('Property accessors resolved:- '+(count << 1)+'<br>');
document.write('Difference from obj.n per accessor:- '+
((base - dur)/(count << 1))+'<br>');
</script>
</body>
</html>

As each comparison function performs two property accesses the count of
the number of calls to the comparison function is doubled in order to
calculate the difference in performance of the particular property
accessor type. Differences that are negative are worse performance than
dot-notation property accessor, and positive results are better
performance. All results are in milliseconds.

The notation - ar - is used to indicate that the subject of the property
accessor is an array and - obj - to indicate when it is an object. The
following are the results of running the page in IE 6, Mozilla 1.5 and
Opera 8.5 on a 500MHz PIII on the Windows 98 operating system:-

500MHz PIII Win 98
IE 6 Mozilla 1.6 Opera 8.5
obj.n ------ ------ ------
ar['1'] -0.0028256 -0.0001109 -0.0021326
ar[1] -0.0033992 -0.0002661 -0.0006042
obj['1'] -0.0035054 -0.0001109 -0.0019548
obj[1] -0.0038666 -0.0001330 -0.0013862

The result that would be predicted form a literal implementation of ECMA
262 would be that dot-notation would be fastest, and so all of the
numbers shown should be negative, and that accessing with a string
should be faster than accessing with an integer, with Array accessing
being slightly slower than Object accessing.

We find that all the numbers are negative, so dot-notation is the
fastest form of property accessor here. And with the exception of Opera
string access is coming up faster than integer access, but (again with
the exception of Opera) Array access appears fractionally faster than
Object access.

Baring in mind that a 500MHz CPU is slow by any current standard and you
would expect to see the measured performance differences in property
accessors getting smaller as CPU speeds increased, the differences
between bracket-notation performance on a single browser range from
0.0015284 (biggest, Opera) to 0.0001552 (smallest, Mozilla)
milliseconds. That is, form 1.5 to 0.15 _millionths_ of a second. That
means that if you want to account for a 6 second difference in outcome
by just changing property accessors you need to be doing between
4,000,000 and 40,000,000 property accessing operations (and more is the
CPU is faster). Notice that IE will sort an random array of 10,000
elements in about 250,000 calls to the comparison function, and very
considerably fewer for smaller arrays.

But now to the "all else being equal" part of the problem. If you want
to attribute performance differences between property accessors to the
javascript implementation, and make deductions from the results as to
the "true" nature of that implementation, you would have to demonstrate
that any differences were entirely attributable to the internal workings
of the implementation and could not be manifestations of other factors.
However, Switch OS and things come out very differently. Repeating the
tests on the same class of CPU; PIII, and the same versions of the same
browsers, but switching to Windows 2000 (and a slightly faster CPU out
of necessity) we get:-

800Mhz PIII Win 2000
IE 6 Mozilla 1.6 Opera 8.5
obj.n ------ ------ ------
ar['1'] -0.0007224 -0.0000200 -0.0008154
ar[1] -0.0110437 0.0000022 -0.0001028
obj['1'] -0.0048314 -0.0000222 -0.0007799
obj[1] -0.0115749 0.0000244 -0.0004254

Given the faster CPU (500Mhz to 800MHz) we would expect the timings to
be about two thirds of the originals, they are not. IE is all over the
place, with some values worse and others better, but at least the
relative positions remain the same; strings are better than numbers and
Array access faster than Object access. On Mozilla we have a total turn
around, number access figures have gone positive and are now better than
dot-notation, but the overall performance difference is much better than
could be accounted for by CPU speed alone. The relative positions of
Opera's results are much the same as the first set but again the
performance difference is greater than could be accounted for by the CPU
speed.

I would expect that if these tests were repeated on other combinations
of CPU and OS we would see different results again. I would anticipate
that Windows XP and a P4 potentially reverse the results across the
board. In the same way as speed testing string comparisons against
regular expressions favours string comparison on PIII Win 98 machines
and regular expressions on Win XP P4 machines. That was an unexpected
phenomenon but makes sense because P4s have hardware optimisation that
favours the sort of things that regular expressions (and video
decompression) need to do and the Windows XP operating system was
written with a knowledge of their potential. Which also explains why the
results above exceed the differences expected by the change of CPU
speed. Windows 98 was written before the PIII existed and cannot fully
exploit any hardware acceleration it provides, while Windows 2000 can
take advantage of its potential (but may not). Windows 2000 will not
exploit the P4's special features, while windows XP may.

The bottom line is that you can time things, and maybe see an obvious
performance benefit in a particular action over another (given testing
on a wide range of browser, CPU and OS combinations indicates that the
perceived benefit is manifest in all/sufficient, and not actually
harmful to some), but you cannot make deductions about the internal
details of javascript implementations from those measurements. You
cannot say that any observed difference is a result of how the
implementation alone is coded because you cannot separate the execution
of the implementation form the OS/CPU environment in which you execute
it, and that combination makes a difference.

On the other hand, this whole thing is a quest for performance in the
wrong place. The differences in the performance of property accessors
are a mater of nanoseconds, you have to be doing millions of them before
it is an issue. Specifically, if you assert that you are sorting arrays
of only "hundreds" of elements and changing the type of property
accessor used makes a difference as large as 6 seconds then the
algorithm you are using is catastrophically bad. It should be to that
that you should be looking to achieve better performance not splitting
hairs over property accessors.

Richard.
Nov 23 '05 #21

P: n/a
On 2005-11-17, ye*****@yahoo.com <ye*****@yahoo.com> wrote:
However, you should read and adhere to <http://jibbering.com/faq/#FAQ2_3>,
especially <http://www.jibbering.com/faq/faq_notes/clj_posts.html>, if you
desire my further help.
thanks for the hot tip!
As I wrote before, you need to post _real_ input and
output data if one is to find a viable transformation algorithm.


is this sufficient? This is as real as I can give you.

sadData[0] =
{lib:"string1,string2,string3,string4",doc:"01,02, 03,04",com:"blah,blah,blah,blah"};


and this is the format I would like to change it to:

happyData[0] = {lib:"string1",doc:"01",com:"blah"};
happyData[1] = {lib:"string2",doc:"02",com:"blah"};
happyData[2] = {lib:"string3",doc:"03",com:"blah"};
happyData[3] = {lib:"string4",doc:"04",com:"blah"};


use split and a for loop.


--

Bye.
Jasen
Nov 23 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.