Array of attribute values from object array?

D

danielbigg

I am new to JavaScript but not to programming. What's the best way of
getting an array of all the values for an attribute in an object
array? I was thinking of using map, e.g.:

var points = [{x: 1, y: 3}, {x: 2, y: 2}, {x: 3, y: 1}];
alert(points.map(function(p){return p.x;}));
alert(points.map(function(p){return p.y;}));

JavaScript seems to be full of all sorts of neat tricks and I would be
surprised if there wasn't a more standard way of doing this without
resorting to loops. Anyone have any ideas?

N.B. I am using the following definition of map:

// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
// http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.map)
{
Array.prototype.map = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var res = new Array(len);
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this)
res = fun.call(thisp, this, i, this);
}
return res;
};
}
 
Z

Zvt.Fred

I am new to JavaScript but not to programming. What's the best way of
getting an array of all the values for an attribute in an object
array? I was thinking of using map, e.g.:

var points = [{x: 1, y: 3}, {x: 2, y: 2}, {x: 3, y: 1}];
alert(points.map(function(p){return p.x;}));
alert(points.map(function(p){return p.y;}));

JavaScript seems to be full of all sorts of neat tricks and I would be
surprised if there wasn't a more standard way of doing this without
resorting to loops. Anyone have any ideas?

N.B. I am using the following definition of map:

// This prototype is provided by the Mozilla foundation and
// is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.map)
{
  Array.prototype.map = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();
    var res = new Array(len);
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
        res = fun.call(thisp, this, i, this);
    }
    return res;
  };

}


Hi Daniel,

I don't know any quick trick to do such operation without loops but I
think that Array.map is Mozilla specific. If you'll use this method
for other things you may define it when your page don't detect it or
your can use define a more-specific function to get just what you want
like this:

var points = [{x: 1, y: 3}, {x: 2, y: 2}, {x: 3, y: 1}];

function getArr(points, prop) {
var len = points.length;
var arr = new Array(len);
for (var i = 0; i < len; i++) arr = points[prop];
return arr;
}

console.log(getArr(points, "x"));
console.log(getArr(points, "y"));

Maybe our gurus know such a trick. :)

Hope it helps.
Fred
 
T

Thomas 'PointedEars' Lahn

I am new to JavaScript but not to programming. What's the best way of
getting an array of all the values for an attribute in an object
array?

If you want to understand any language, take care of your vocabulary.
Objects are an unordered collection of *properties* (markup elements and
interfaces have attributes instead). Object objects are different from
Array objects. You have an Array object that holds references to Object
objects here, and you refer to that Array object by a variable named
`points' which (after assignment) holds a reference (value) to that object.
I was thinking of using map, e.g.:

var points = [{x: 1, y: 3}, {x: 2, y: 2}, {x: 3, y: 1}];
alert(points.map(function(p){return p.x;}));
alert(points.map(function(p){return p.y;}));

Actually, it is window.alert() (and thus should be called so), and it is no
longer part of the JavaScript language (since JavaScript 1.4) but provided
by a host-dependent API, the (Gecko) DOM. AFAWK, it has never been part of
Microsoft JScript or other ECMAScript implementations.
JavaScript seems to be full of all sorts of neat tricks and I would be
surprised if there wasn't a more standard way of doing this without
resorting to loops.

Be surprised, then. The language standard is ECMAScript (currently Ed. 3)
and does not specify such a method. JavaScript is one of many (but probably
together with JScript one of the most prominent) ECMAScript implementations
and provides (in agreement with the standard's Conformance section) the
Array.prototype.map() method, but only since version 1.6 (Firefox 1.5+ and
other browsers that are based on the same or newer Gecko version).

Also since version 1.6, JavaScript provides the `for each' statement as part
of its support for ECMAScript for XML (E4X, ECMA-357). And as another
proprietary extension, JavaScript provides Array comprehensions since
version 1.7 (Firefox 2.0+ and Gecko compatibles). This can be combined into

[o.x for each (o in [{x: 1, y: 3}, {x: 2, y: 2}, {x: 3, y: 1}])]

However, this is still a loop, and far from being specified in a standard.
It is thus not supported by any version of Internet Explorer, Opera or
Safari yet, which again points out that there is not a single language but
several different ECMAScript implementations one has to deal with.

See also said:
Anyone have any ideas?

N.B. I am using the following definition of map:

Understand that you only need that for compatibility in non-Geckos or older
Geckos (see above); therefore, it is preserved when defined (there):
if (!Array.prototype.map)
{
Array.prototype.map = function(fun /*, thisp*/)
[...]

However, that workaround employs too superficial a feature test. Search for
`isMethod' for a better one.


HTH

PointedEars
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
Actually, it is window.alert() (and thus should be called so),

Why? If you are doing normal web page scripting, the window object
is also the global object, and "alert" will refer to the same function.

Referring to "alert" unqualified is no different from referring to
"window" unqualified. If you can do the latter, you can do the former
as well.

/L
 
G

Gregor Kofler

Am Sun, 12 Apr 2009 02:49:24 +0200 schrieb Lasse Reichstein Nielsen:
Why? If you are doing normal web page scripting, the window object is
also the global object, and "alert" will refer to the same function.

Referring to "alert" unqualified is no different from referring to
"window" unqualified. If you can do the latter, you can do the former as
well.

/L

Unless of course you have an alert function or property somewhere along
your scope chain.
With nowadays practice of mashing scripts (of often dubious origin) I'd
rather go for the definitely hassle-free window.alert() - I suppose one
can afford the extra 7 Bytes.

Gregor
 
T

Timo Reitz

Gregor said:
Unless of course you have an alert function or property somewhere along
your scope chain.
With nowadays practice of mashing scripts (of often dubious origin) I'd
rather go for the definitely hassle-free window.alert() - I suppose one
can afford the extra 7 Bytes.

But window.alert() won't work as expected if I have a window object along my
scope chain.
 
D

David Mark

But window.alert() won't work as expected if I have a window object alongmy
scope chain.

One train of thought says it shouldn't be an implied global either.
The other says you have to draw the line somewhere and window is a
good point.

If you want to support non-browsers:

var GLOBAL = this.window || this;

GLOBAL.alert('Assumed nothing');

If you only care about browsers:

window.alert('Assumed a browser');

Don't do this:

alert('Made some bad assumptions');

As with any host method, test alert before use. Also, avoid this
method (and the like) whenever possible (it is easy enough to write
replacements that do not block the browser UI.)
 
S

SteveYoungTbird

Thomas said:
Actually, it is window.alert() (and thus should be called so), and it is no
longer part of the JavaScript language (since JavaScript 1.4) but provided
by a host-dependent API, the (Gecko) DOM. AFAWK, it has never been part of
Microsoft JScript or other ECMAScript implementations.

Every single JavaScript tutorial and reference book that I have ever
seen refer to the the window.alert() method as a JavaScript method.

Now Thomas Lahn flippantly explains that it is no longer part of the
JavaScript language and confusingly adds that "AFAWK, it has never been
part of Microsoft JScript or other ECMAScript implementations."

I have a few questions for Thomas regarding his extraordinary statement.
I'll ask two of them now and see whether he is in a helpful or abusive
mood before asking the others.

1) If windows.alert has never been part of Microsoft JScript or other
ECMAScript implementations how can it be no longer part of JavaScript
which is an ECMAScript implementation is it not? In other words how can
it be "no longer" part of something it was never part of?

2) AFAWK usually means "as far as we know". Why should it be difficult
to say whether windows.alert was a part of Microsoft JScript or other
ECMAScript implementations or not.

Regards, Steve.
 
D

David Mark

Every single JavaScript tutorial and reference book that I have ever
seen refer to the the window.alert() method as a JavaScript method.

Take them back.
Now Thomas Lahn flippantly explains that it is no longer part of the
JavaScript language and confusingly adds that "AFAWK, it has never been
part of Microsoft JScript or other ECMAScript implementations."

It hasn't.
I have a few questions for Thomas regarding his extraordinary statement.
I'll ask two of them now and see whether he is in a helpful or abusive
mood before asking the others.

You should write Thomas at his address.
1) If windows.alert has never been part of Microsoft JScript or other
ECMAScript implementations how can it be no longer part of JavaScript
which is an ECMAScript implementation is it not? In other words how can
it be "no longer" part of something it was never part of?

You've got a chicken and egg problem here. See the description of
this group.
2) AFAWK usually means "as far as we know". Why should it be difficult
to say whether windows.alert was a part of Microsoft JScript or other
ECMAScript implementations or not.

Can you name all of the implementations?
 
G

Garrett Smith

David said:
Gregor Kofler schrieb:
[...]


Don't do this:

alert('Made some bad assumptions');

As with any host method, test alert before use. Also, avoid this

Test what? typeof window.alert != "undefined"?

A safeguard for any new browsers that decide to not implement alert?

No thanks. I'll let those browsers fail (and avoid the typechecking
clutter).
method (and the like) whenever possible (it is easy enough to write
replacements that do not block the browser UI.)

Agreed. Alert, being modal, is generally bad user experience.

Garrett
 
D

David Mark

David said:
Gregor Kofler schrieb:
[...]



Don't do this:
alert('Made some bad assumptions');
As with any host method, test alert before use.  Also, avoid this

Test what? typeof window.alert != "undefined"?

Detect is what I meant. That is the short form.
A safeguard for any new browsers that decide to not implement alert?

Any environment that does not support alert (or has it disabled for
some reason.) Why skip that method in particular?
No thanks. I'll let those browsers fail (and avoid the typechecking
clutter).

I would rather skip the enhancement altogether than allow it to
proceed and throw an exception. I don't want to have to think about
recovering from such unexpected circumstances. In some cases, it
could cause more than just a log entry.

[snip]
 
Z

Zvt.Fred

Zvt.Fred wrote:

[...]
   function getArr(points, prop) {
   var len = points.length;
   var arr = new Array(len);
   for (var i = 0; i < len; i++) arr = points[prop];
   return arr;
   }


`getArr` is a strange choice of name for a function that returns certain
property of every array item. Maybe `mapProperty`?

[...]


I agree. Actually I did not think much about it. :)
Thanks for the heads up!

Fred
 

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