2

So I had a situation where I was creating reports and wanted a structure like so in javascript:

data[2015][2] = {
   property: value,
   property2: value
};

I didn't like creating an array because I felt that it was a waste having a 2015 element array for something that I would only have recent years for so I tried .toString() and adding it as a property but this does not work (I know numbers can't be property names in languages like .net but wasn't sure about javascript being new to the language). I ended up just appending a 'y_' for year and 'm_' for month and it works fine, but my question is would there have been a better way to do this? Was I just being paranoid about having a 2015 element array full of undefined?

3
  • 1
    Arrays don't necessarily work like you think they do in JavaScript. Commented Mar 12, 2015 at 3:50
  • 1
    You can use a number (it will be cast to string) as a property name but you should at first initialise the array: data[2015] = [] Commented Mar 12, 2015 at 3:56
  • All the answers were very helpful as well as the comments... thank you guys for the help in understanding javascript arrays! Commented Mar 12, 2015 at 15:28

3 Answers 3

4

You could use a object rather than an array. You are allowed to use numbers as keys as long as they are a string. So in keeping with your layout you could do something like this:

data = {
    "2015": [
        "array_elem_0",
        "array_elem_1",
        {
            "property": value,
            "property2": value
        }
    ]
}

Then when you need to index into the object use

data["2015"] ...
Sign up to request clarification or add additional context in comments.

2 Comments

There is no JSON object. JSON is a string. Also you should use : for defining a property.
Note that data[2015] also works for the above object. Try it.
4

The syntax you use is perfectly valid for either arrays or objects. Javascript allows the use of numbers as property names but it auto-converts it to a string (you normally wouldn't notice it). All that you need to do is to initialize your variable as an object instead of an array:

var data = {};
data[2015] = {};
data[2015][2] = ...

To prove that data is, in fact, not an array, you can try to check its length:

console.log(data.length); // undefined

As I mentioned, the numbers are automatically converted to strings. The following all point to the same data:

data[2015][2];
data["2015"]["2"];
data["20" + "15"][1+1];

Side note:

Traditionally, you can even use an array and not worry about memory because javascript arrays were traditionally implemented as sparse arrays. But modern browsers may optimize some arrays to be actual arrays so if you really want to save memory use objects instead.

Comments

1

Although here are already two good answers, I'd like to specifically address your question if you feel "paranoid" to use an array with many unfilled elements.

JS arrays are tricky as they may appear as "linear lists" as well as "dictionaries". If you use them as "dictionary", you are actually using JS Object properties. So you are mixing contents.

Try this:

var a = [];
a[10] = "the entry";
console.log("A seems to have a length of: " + a.length);

console.log ("Contents of a:");
for (var key in a) {
  console.log("- key " + key + " has: " + a[key]);
} 

Result:

"A seems to have a length of: 11"
"Contents of a:"
"- key 10 has: the entry"

There is actually only one element stored. This shows that length is just an information. It is an upper border that has been set in order to keep the array consistent, if it is seen as integer-addressed chain of elements. Here, length is not related to "size of memory allocated". There are no "empty storage places".

For some followup questions, you may try this change too:

var a = [];

a[5] = "the earlier entry";
a["the_key"] = "disturbing";
a["2015"] = "Top";

a[10] = "the entry";
console.log("A seems to have a length of: " + a.length);

console.log ("Contents of a:");
for (var key in a) {
  console.log("- key " + key + " has: " + a[key]);
} 

New result:

"A seems to have a length of: 2016"
"Contents of a:"
"- key 5 has: the earlier entry"
"- key 10 has: the entry"
"- key 2015 has: Top" 
"- key the_key has: disturbing"

You can always use the Array context as well as the Object context.

This has consequences, e.g. for how to loop an array (it is already a huge discussion, jQuery's .each() adds some more questions :-) ).

With the classic for loop, you have to check if an element is undefined. (Remove the above key "2015" first).

for (var i=0; i<a.length; i++) {
  console.log("at i=" + i + ": " + a[i]);
}

Shows:

"at i=0: undefined"  
"at i=1: undefined"
"at i=2: undefined"
"at i=3: undefined"
"at i=4: undefined"    
"at i=5: the earlier entry"  <<<
"at i=6: undefined"
"at i=7: undefined"
"at i=8: undefined"
"at i=9: undefined"
"at i=10: the entry"  <<<

The object loop with in shows the keys.

Finally, it seems you have clarify the Array methods how they act for a linear array and if this is what you expect. indexOf(), for example, acts like for a linear array. indexOf() is defined for Array, not for Object. Therefore indexOf() won't return you an alphanumeric key but only linear index positions.

http://www.javascripture.com/Array

http://www.ecma-international.org/ecma-262/5.1/#sec-15.4

1 Comment

this answer was very through and helped me a lot in understanding arrays in js.. thanks for posting!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.