JSON and asscociative arrays

K

Kees

I'am new to JSON and below is a problem I've found

this works:
var arr= new Array();
arr[0]='xxx';
arr[1]='yyy';
alert(arr.stringify()); // shows "[\"xxx\", \"yyy\"]"

but this won't
var arr= new Array();
arr['x']='xxx';
arr['y']='yyy';
alert(JSON.stringify(arr)); // shows "[]"

How can I stringify a associative array?
Do I have to convert it to Object???


Greetings
Kees
 
E

Evertjan.

Kees wrote on 30 dec 2008 in comp.lang.javascript:
I'am new to JSON and below is a problem I've found

this works:
var arr= new Array();
arr[0]='xxx';
arr[1]='yyy';
alert(arr.stringify()); // shows "[\"xxx\", \"yyy\"]"

but this won't
var arr= new Array();
arr['x']='xxx';
arr['y']='yyy';
alert(JSON.stringify(arr)); // shows "[]"

How can I stringify a associative array?
Do I have to convert it to Object???

arr['x'] is NOT a member of the array arr,
it is a property of the object arr.

more logical would be:

var arr= {}; // object
arr['x']='xxx';
arr['y']='yyy';

Then:
I have no idea what "stringify()" is,
[and I do not want to know,
since it is not basic Javascript],
probably that function expects a filled array.
 
S

Stevo

Kees said:
I'am new to JSON and below is a problem I've found

this works:
var arr= new Array();
arr[0]='xxx';
arr[1]='yyy';
alert(arr.stringify()); // shows "[\"xxx\", \"yyy\"]"

but this won't
var arr= new Array();
arr['x']='xxx';
arr['y']='yyy';
alert(JSON.stringify(arr)); // shows "[]"

How can I stringify a associative array?
Do I have to convert it to Object???

What's wrong with using the same syntax you used first time?
alert(arr.stringify());

You haven't shown us the JSON or stringify definitions.
 
S

Stevo

Conrad said:
I have no idea what "stringify()" is,
[and I do not want to know,
since it is not basic Javascript],
probably that function expects a filled array.

You may not want to know it, but since Stevo asked as well and the

I also don't want to know :)
method is used very frequently, I'm telling you anyway :)

Not listening. La La La La La (hands over ears and eyes) :)
It's (probably, can't be sure in this specific case) from Douglas
Crockford's json2.js library.

Yeah that does sound vaguely familiar now you mention it. I half recall
seeing that in those YUI theatre videos that Dougie made.
 
G

Gregor Kofler

Kees meinte:
I'am new to JSON and below is a problem I've found

this works:
var arr= new Array();
arr[0]='xxx';
arr[1]='yyy';
alert(arr.stringify()); // shows "[\"xxx\", \"yyy\"]"

but this won't
var arr= new Array();
arr['x']='xxx';
arr['y']='yyy';
alert(JSON.stringify(arr)); // shows "[]"
How can I stringify a associative array?

There are no "assoicative arrays" in JS.
Do I have to convert it to Object???

Since they don't exist, they can't be converted. But a "normal" object
will probably do the job.

Try

var foo = {};
foo['x'] = 'xxx'; // or foo.x = ...
foo['y'] = 'yyy'; // or foo.y = ...
alert(JSON.stringify(foo));

Just realize that foo is *not* an array, and lacks certain properties
inherent to arrays.

Gregor
 
J

Jeremy J Starcher

I'am new to JSON and below is a problem I've found

What JSON library are you using? There is no standard
Javascript .stringify method.
this works:
var arr= new Array();
arr[0]='xxx';
arr[1]='yyy';
alert(arr.stringify()); // shows "[\"xxx\", \"yyy\"]"

This is correct.
but this won't
var arr= new Array();
arr['x']='xxx';
arr['y']='yyy';
alert(JSON.stringify(arr)); // shows "[]"

Again, this is correct.
How can I stringify a associative array?

Javascript does not have associative arrays as such, but it DOES have
objects which are very similar (and frequently mistaken for).

VERY quick comparision:
Javascript objects:
* Have string property names
* Can be iterated over, but the order is undefined.

Javascript arrays:
* Have integer indexes
* Can be iterated over in numeric order.

In your second example, you created an array, then set properties on it.

Try this:
var p= {}; // An object literal
o['x']='xxx'; // Can also be written as o.x
o['y']='yyy'; // Can also be written as o.y
alert(JSON.stringify(o)); // shows "[]"




It would be well worth your time to study the difference between objects
and arrays, since arrays *are* an object with stuff added on.
 
J

Jorge

How can I stringify a associative array?

You can't.

When an object is expressed as a JSON text, the properties' names are
declared explicitly:

var object= {};
object['0']= 6;
object['1']= 6;
object['2']= 6;
object.x= "xxx"; -> JSON text '{ "0":6, "1":6, "2":6, "x":"xxx" }'

But when an Array is expressed as a JSON text (even though its indices
are in fact properties of an (array-like) Array-object) the indexes
aren't explicitly declared, and that's why non-numeric (Array) indexes
can't be expressed in a JSON text:

var array= [6,6,6]; -> JSON text "[6,6,6]" -> the indices 0,1,2 are
implicit.
array["5"]= 6; -> JSON text "[6,6,6,,,6]" -> the indices 0,1,2,3,4,5
are implicit...
array["x"]= "xxx"; -> Array indexes can't be explicited: the "x" index
would be lost if/when stringified.
 
T

Thomas 'PointedEars' Lahn

Jorge said:
You can't.

If there was such an thing as an associative array in ECMAScript,
certainly you could. But what was meant here was a simple Object object,
and definitely one can iterate over (the properties of) such an object
(it is only a matter of how, see also my other posting).
When an object is expressed as a JSON text, the properties' names are
declared explicitly:

var object= {};
object['0']= 6;
object['1']= 6;
object['2']= 6;
object.x= "xxx"; -> JSON text '{ "0":6, "1":6, "2":6, "x":"xxx" }'

But when an Array is expressed as a JSON text (even though its indices
are in fact properties of an (array-like) Array-object) the indexes
aren't explicitly declared, and that's why non-numeric (Array) indexes
can't be expressed in a JSON text:

Only very rougly speaking. In fact, an array in JSON is written like an
ECMAScript Array initializer (‘[...]’) which only allows to add (not:
declare) properties with numeric name, in numeric ascending order, to
the newly constructed Array object.

If property addition order or property names are not to be numerical
ascending, JSON object syntax must be used instead which is close to
ECMAScript Object initializers (‘{...}’). (AFAIK, the only difference
between the former and the latter being that the former requires all
property names to be quoted, the latter only non-Identifiers.)

Those two ways can be combined easily. In this case, the following might
help:

{"a": [6, /5/, "4"], "x": "xxx"}

This, when parsed as an Object object referred to here as ‘o’, can be
iterated over as follows:

for (var p in o)
{
var v = o[p];
if (v.constructor == Array)
{
for (var i = 0, len = v.length; i < len; i++)
{
var e = v;
// ...
}
}
else
{
// ...
}
}

This code is a stub. Generation of the string representation of this
object (and a uniform more object-oriented way to generate and return
the string representation of any Object or Array object) is left as an
exercise to the reader. Please observe the usual security precautions.



PointedEars
 
T

Thomas 'PointedEars' Lahn

Jeremy said:
Kees wrote:

Javascript does not have associative arrays as such, but it DOES have
objects which are very similar (and frequently mistaken for).

VERY quick comparision:
Javascript objects:
* Have string property names
* Can be iterated over, but the order is undefined.

Javascript arrays:
* Have integer indexes
* Can be iterated over in numeric order.

In fact, JS arrays are Array objects, and thus can be iterated over in
at least those two ways, which are exactly:

1) for..in-iteration: iterates over the enumerable properties (inherited
and not inherited) of any object in unspecified order.

2) for/while-iteration: can iterate over properties in
developer-specified order. The most simple and thus frequently taken
approach is to iterate over properties which names can be interpreted as
numbers in ascending or descending numeric order. In any case, those
properties do not need to be enumerable (don't need to have the DontEnum
flag set, and in some implementations even the "numeric" properties of
Array objects don't have it) because their names are already known and
can thus be used with the bracket property accessor syntax.
[...]
It would be well worth your time to study the difference between
objects
and arrays, since arrays *are* an object with stuff added on.

Yes, you should.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
2) for/while-iteration: can iterate over properties in
developer-specified order. The most simple and thus frequently taken
approach is to iterate over properties which names can be interpreted
as
numbers in ascending or descending numeric order. In any case, those
properties do not need to be enumerable (don't need to have the
DontEnum
flag set, and in some implementations even the "numeric" properties of
Array objects don't have it) because their names are already known and
can thus be used with the bracket property accessor syntax.

Correction/clarification:

In some implementations of ECMAScript, the properties that have a name
that can be interpreted as (unsigned 32-bit integer) numbers (those
which designate array elements) *have* the DontEnum flag set which is
why

for (var i in a)

is not an interoperable way to iterate over the elements of the Array
‘a’ (regardless of the unspecified iteration order).


PointedEars
 
L

Logos

How can I stringify a associative array?
Do I  have to convert it to Object???

Greetings
Kees

I'll chime in and tell you that there are no associative arrays in
js. And you don't HAVE to convert it to an object, but it makes a lot
more sense to do so.

I can also show you a quick & dirty function that should act like
'stringify' on objects (tho I'm sure you could build it yourself
without much effort).

function stringifyObj(o) {
var stringified = "";

if (typeof(o) == "object") {
var stringified = "{";
var first =true;

for (var key in o) {
if(!first) { stringified +=","; }
else { first =false; }
stringified +=(typeof(o[key]) == "object") ? stringifyObj(o[key]) :
'"' +key +'":"' +o[key] +'"';
}

stringified +="}";
}

return stringified;
}

My test example:
alert(stringifyObj({"moo":"poo","ju":"gu","leelu":{"1":"2",
"3":"4"}}));

Hope that's helpful!

Tyler Style
http://www.malthusian-solutions.com
http://nirdvana.com
 
D

dhtml

Thomas said:
Correction/clarification:

In some implementations of ECMAScript, the properties that have a name
that can be interpreted as (unsigned 32-bit integer) numbers (those
which designate array elements) *have* the DontEnum flag set which is
why

for (var i in a)

is not an interoperable way to iterate over the elements of the Array
‘a’ (regardless of the unspecified iteration order).

It sounds like you're saying that some implementations, given:-

var a = [0];
for(var p in a) {
alert(a[p]);
}

alert would not be called.

Which implementations?
 
J

Jeremy J Starcher

In fact, JS arrays are Array objects, and thus can be iterated over in
at least those two ways, which are exactly:

ACK, but I was giving milk to a babe. Not meat. I spoke the truth, but
not everyone is ready for the whole truth (yet).

[Additional explanation snipped]

I know that Arrays are objects and inherit all of the abilities of
objects, including property iteration.

In fact, I did say so just a few lines later.
[...]
It would be well worth your time to study the difference between
objects
and arrays, since arrays *are* an object with stuff added on.

Yes, you should.

I'll admit, you did get me on this one though:
The most simple and thus frequently taken
approach is to iterate over properties which names can be interpreted as
numbers in ascending or descending numeric order. In any case, those
properties do not need to be enumerable (don't need to have the DontEnum
flag set, and in some implementations even the "numeric" properties of
Array objects don't have it)

I was not aware that some implementations set DontEnum on Array
elements. One of those things to remember, but I hope I never see code
where that matters.
 

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,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top