Help. Finding max value in array of objects.

T

timothytoe

Situation:

I have an array of objects. I want to find the maximum value of a
given numeric value that exists in each of the objects. Suppose the
array of objects is called "stat" and the numeric value I want to
check is called "member".

Obviously, a for loop would do it:

var maximum=stat.member[0];
for (i=1;i<stat.length;i++) {
if (stat.member>maximum) {
maximum=stat.member;
}
}

But is there a better way? I know how to bend Math.max to my will to
have is find the max value of an array. Could it be forced into
servitude to solve this case? Or perhaps there's a relatively clean
way to use sort here?

Ideally, I'd want to have a function that takes the name of the
element I want to check.

maximum=getMax(stat,"member");

Looking for a clear, compact solution. Clever is optional.
 
J

Joost Diepenmaat

timothytoe said:
Situation:

I have an array of objects. I want to find the maximum value of a
given numeric value that exists in each of the objects. Suppose the
array of objects is called "stat" and the numeric value I want to
check is called "member".

Obviously, a for loop would do it:

var maximum=stat.member[0];
for (i=1;i<stat.length;i++) {
if (stat.member>maximum) {
maximum=stat.member;
}
}

But is there a better way? I know how to bend Math.max to my will to
have is find the max value of an array. Could it be forced into
servitude to solve this case? Or perhaps there's a relatively clean
way to use sort here?

Ideally, I'd want to have a function that takes the name of the
element I want to check.

maximum=getMax(stat,"member");

Looking for a clear, compact solution. Clever is optional.


If you have javascript 1.8 (probably not, but see below):

var max = stat.reduce( function(a,b) { return a > b ? a : b } );

For older versions: there's a definition of Array.prototype.reduce at

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:reduce

Joost.
 
T

timothytoe

timothytoe said:
Situation:
I have an array of objects. I want to find the maximum value of a
given numeric value that exists in each of the objects. Suppose the
array of objects is called "stat" and the numeric value I want to
check is called "member".
Obviously, a for loop would do it:
var maximum=stat.member[0];
for (i=1;i<stat.length;i++) {
if (stat.member>maximum) {
maximum=stat.member;
}
}

But is there a better way? I know how to bend Math.max to my will to
have is find the max value of an array. Could it be forced into
servitude to solve this case? Or perhaps there's a relatively clean
way to use sort here?
Ideally, I'd want to have a function that takes the name of the
element I want to check.

Looking for a clear, compact solution. Clever is optional.

If you have javascript 1.8 (probably not, but see below):

var max = stat.reduce( function(a,b) { return a > b ? a : b } );

For older versions: there's a definition of Array.prototype.reduce at

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Ob...

Joost.


Oh. That's cool. Probably only worth it if I would want to use reduce
in more places than one.
 
J

Joost Diepenmaat

timothytoe said:
Oh. That's cool. Probably only worth it if I would want to use reduce
in more places than one.

Sure, but you it will at least let you implement max(), min(),
average(), total(), all() and none() very easily.

Just keep it in mind if you want to reduce a list of values to a single
value.

Likewise, map and filter are also pretty useful (maybe even more useful):

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:map
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter

I use those daily.

Joost.
 
T

timothytoe

maximum= array.sort()[array.length-1]
Mick

I don't quite get that. You're ignoring "member." I'm not just looking
for the max in an array. I'm looking for the maximum of an element in
an object in an array.

For that matter, Joost ignored it too. Neither solution works as is.
 
J

Joost Diepenmaat

timothytoe said:
maximum= array.sort()[array.length-1]
Mick

I don't quite get that. You're ignoring "member." I'm not just looking
for the max in an array. I'm looking for the maximum of an element in
an object in an array.

For that matter, Joost ignored it too. Neither solution works as is.

stat.map(
function(m) { return m.member } ).reduce(
function (a,b) { a > b ? a : b } );

Joost.
 
T

timothytoe

timothytoe said:
maximum= array.sort()[array.length-1]
Mick
I don't quite get that. You're ignoring "member." I'm not just looking
for the max in an array. I'm looking for the maximum of an element in
an object in an array.
For that matter, Joost ignored it too. Neither solution works as is.

array == stat.member, no?
maximum= stat.member.sort()[stat.member.length-1]

or I'm missing something.
Mick

Maybe I'm misunderstanding your solution.

member is not an array. It's a number.
it's an array of objects. Each object has a member.

I see that I screwed up my code, which is how I threw everyone off.

Should have been:

var maximum=stat[0].member;
for (i=1;i<stat.length;i++) {
if (stat.member]>maximum) {
maximum=stat.member;
}
}

Sorry about that.
 
A

AKS

Situation:

I have an array of objects. I want to find the maximum value of a
given numeric value that exists in each of the objects. Suppose the
array of objects is called "stat" and the numeric value I want to
check is called "member".

var stat = [{ member: -1 }, { member: 1 },
{ member: 20 }, { member: 5 }];

var toString = Object.prototype.toString;

Object.prototype.toString = function () {
return this.member;
};

alert(Math.min.apply(null, stat)); // => 20

Object.prototype.toString = toString;
 
D

Dr J R Stockton

Wed said:
If you have javascript 1.8 (probably not, but see below):

The default assumption here is that code is for an Internet Web page.
Except for ease of testing, it is then irrelevant which JavaScript
version the author has. What matters is which versions the potential
readers will have.

It would be useful if the FAQ were to list, or explicitly link to, a
chronological table showing when the major browsers were released, and
which versions of JavaScript they came with.

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 
T

timothytoe

Situation:
I have an array of objects. I want to find the maximum value of a
given numeric value that exists in each of the objects. Suppose the
array of objects is called "stat" and the numeric value I want to
check is called "member".

var stat = [{ member: -1 }, { member: 1 },
{ member: 20 }, { member: 5 }];

var toString = Object.prototype.toString;

Object.prototype.toString = function () {
return this.member;

};

alert(Math.min.apply(null, stat)); // => 20

Object.prototype.toString = toString;

Ah. Good. I get it.
 
J

Joost Diepenmaat

Dr J R Stockton said:
The default assumption here is that code is for an Internet Web page.
Except for ease of testing, it is then irrelevant which JavaScript
version the author has. What matters is which versions the potential
readers will have.

It would be useful if the FAQ were to list, or explicitly link to, a
chronological table showing when the major browsers were released, and
which versions of JavaScript they came with.

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.

Did you read on?

Joost.
 
D

Dr J R Stockton

In comp.lang.javascript message <93773b24-dac8-44f6-9aaa-d6676ac1c0e7@e2
5g2000prg.googlegroups.com>, Wed, 6 Feb 2008 10:10:25, timothytoe
Or perhaps there's a relatively clean
way to use sort here?

If the number of items to be checked is small, any method that gives the
right answer will do. Otherwise, scanning will inevitably be faster
than sorting, since sorting is a more complex operation.

If there is any possibility of the array being empty, initialise the
result to NaN and change the comparison from greater to not (less)
to accommodate comparison with NaN giving false.

A counting-to-zero loop can be expected to be slightly faster.

You had, somewhere in the thread,
if (stat.member]>maximum) { maximum=stat.member; }
If it is likely that the entries are nearly in ascending order, then
consider if ((T=stat.member])>maximum) { maximum=T; }
 
D

Dr J R Stockton

Did you read on?

Yes. It makes no difference. The important point is that it is not the
browser(s) that "you" have (you, JD, were replying to the OP, who is
presumed to be an author) have that matters ; it is the browsers that
the author's readers have. AISB.

The distinction between author's system and readers' systems is too
often forgotten.

Please do not over-quote.
 
J

Joost Diepenmaat

Dr J R Stockton said:
Yes. It makes no difference. The important point is that it is not the
browser(s) that "you" have (you, JD, were replying to the OP, who is
presumed to be an author) have that matters ; it is the browsers that
the author's readers have. AISB.

I'm not arguing the technical point, I was just trying to be concise.

IOW I was contracting "the browser you and everybody else who's viewing
the site is using to view the site have javascript version 1.8 or higher
and have it enabled at that time" to "you have javascript 1.8". Yes it's
sloppy, but I think it got the point across in this case.
The distinction between author's system and readers' systems is too
often forgotten.

Sure. Fair enough.
 
T

Thomas 'PointedEars' Lahn

Dr said:
It would be useful if the FAQ were to list, or explicitly link to, a
chronological table showing when the major browsers were released, and
which versions of JavaScript they came with.

Such a list exists already and has been referred to here several times before:

http://PointedEars.de/es-matrix
(note the Version Information links)

As for the Language Features, more testing and maybe augmentation is
required. Feedback of the inclined reader is therefore much appreciated.

It should also be noted that for JScript it is possible that an older
version of Internet Explorer supports a newer version of JScript than it was
originally shipped with through an update of the Microsoft Script Engine.
That is not possible, or in the Mozilla.org days at least unlikely, with
JavaScript.


PointedEars
 
T

Thomas 'PointedEars' Lahn

timothytoe said:
[Michael White wrote:]
maximum= array.sort()[array.length-1]

I don't quite get that. You're ignoring "member." I'm not just looking
for the max in an array. I'm looking for the maximum of an element in
an object in an array.

function array_comp(a, b)
{
if (a.member < b.member)
{
return -1;
}
else if (a.member > b.member)
{
return 1;
}

return 0;
}

array.sort(array_comp);
var maximum = array[array.length - 1];

However, I think that iterating through the array is in most cases more
efficient than sorting it and retrieving the last element. The former
algorithm has a complexity of O(n) in the Worst Case, even Heapsort has
O(n * log(n)) then. Meaning it is already slower with 3 or more unsorted items.

Furthermore, Array.prototype.sort() is a mutator method, and you might not
want the array items to be sorted.

But you said:

And if we assume that you meant what you wrote, that `stat' was a reference
to an Array object, your posted approach is wrong to begin with --

[pretty-printed]
var maximum = stat.member[0];
for (i = 1; i < stat.length; i++) {
if (stat.member > maximum) {
maximum = stat.member;
}
}


-- because that would imply both `stat' and `stat.member' were iterable.

Probably you were looking for this instead:

var maximum = Number.NEGATIVE_INFINITY;

for (i = 0; i < stat.length; i++)
{
if (stat.member > maximum)
{
maximum = stat.member;
}
}

It would then be possible to optimize it slightly:

var maximum = Number.NEGATIVE_INFINITY;

for (i = stat.length; i--;)
{
var value = stat.member;
if (value > maximum)
{
maximum = value;
}
}

And if you were to optimize it in all places, Array.prototype.map() or a
called equivalent implementation would probably be best regarding efficiency
and future maintenance effort.


Please leave the attribution line in, and don't quote the signature instead.


PointedEars
 
T

Thomas 'PointedEars' Lahn

timothytoe said:
Situation:
I have an array of objects. I want to find the maximum value of a
given numeric value that exists in each of the objects. Suppose the
array of objects is called "stat" and the numeric value I want to
check is called "member".
var stat = [{ member: -1 }, { member: 1 },
{ member: 20 }, { member: 5 }];

var toString = Object.prototype.toString;

Object.prototype.toString = function () {
return this.member;

};

alert(Math.min.apply(null, stat)); // => 20

Object.prototype.toString = toString;

Ah. Good. I get it.

I hope you do, because it does have drawbacks:

- Function.protototype.apply() may not be supported
(JavaScript < 1.3, JScript < 5.5, ECMAScript < 3)

- Math.min() or Math.max() may not support more than two arguments
(JavaScript < 1.5, JScript < 5.5, ECMAScript < 3)

See also http://PointedEars.de/es-matrix#m (updated)

As a workaround for the former,

window.alert(Math.min.apply(null, stat));

is equivalent to

this.min = Math.min;
window.alert(this.min(stat[0], stat[1], stat[2], stat[3]));
delete this.min;

in global context here. A universal workaround for
Function.prototype.apply() could probably only be realized with eval().


PointedEars
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>, Sun,
10 Feb 2008 14:29:25 said:
However, I think that iterating through the array is in most cases more
efficient than sorting it and retrieving the last element. The former
algorithm has a complexity of O(n) in the Worst Case, even Heapsort has
O(n * log(n)) then. Meaning it is already slower with 3 or more unsorted items.

The last sentence is not a valid deduction from what precedes it.
 

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,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top