4

How to initialize a string array (size<100 items) in javascript whose indexes are scattered over entire integer range, with data items.

If I do like this:

array1 = ["string1","string2","string3","string4"];

then I get array of length 4 with indices ranging 0 to 3

But in my case i want to keep my own indices, so that the array could be used like a high performance int-string hash table.

I'm preferably looking out for a single statement initialization.

The items of the array should be accessible like this: array1[23454]

Update From Comments

I'm restricted to initialize the array as a single statement since a dynamically prepared array initialization string is appended from server side like this: var array = <string from server here>

Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294
  • You could use an object literal, but you loose the array methods then. If it does not have to be one statement, just create an empty array and set the indexes you need. – Felix Kling Oct 25 '12 at 16:13
  • & also high performance retrievals obtained with an array with integer indexes, no ? – Rajat Gupta Oct 25 '12 at 16:15
  • 2
    Don't know what you mean, arrays are just object as well. If there is a performance difference it is implementation dependent. – Felix Kling Oct 25 '12 at 16:19
  • Actually I need to use array like a hashtable to store int string pairs. Since my keys are all ints I want to avoid the toString() conversion done while storing items in the array object. – Rajat Gupta Oct 25 '12 at 16:28
  • Then just use object `var obj = {}; obj[hash] = value;` – SReject Oct 25 '12 at 16:29
  • @user01: Even array keys are converted to strings, because, as said, arrays are just objects with some extra methods/logic. How the data is stored is the same (unless the implementation provides an optimization for arrays, but I don't know about that). – Felix Kling Oct 25 '12 at 17:31
  • @Felix Kling: ok, so according to you what is the best(*high performance*) way to store int-string pairs(as if in a hashmap / hashtable) for retrievals using int keys. – Rajat Gupta Oct 25 '12 at 17:36
  • 1
    In terms of access or creation? For the latter, objects seem to perform best in Chrome 22 and Firefox 15 (http://jsperf.com/object-vs-array-comparison), which makes sense because there is no overhead from the array logic. Access times should be the same in both cases. – Felix Kling Oct 25 '12 at 17:47

4 Answers4

2

To create an array with a set number of indexes you can use

// Creates an array with 12 indexes
var myArray = new Array(12);

This isn't needed in javascript due to the way its array's work. There isn't an upper-bound for arrays. If you try to reference an item index in the array that doesn't exist, undefined is returned but no error is thrown

To create an array with perscribed indexes you can use something like array['index'] = value though this would force you to use multiple statements. Javascript doesn't have an array initalizer to allow for you to specify indexes and values all in a single statement though you can create a function to do as such

function indexArray(param) {
    var a = [], i;
    for (i=0; i<param.length; i+=1) {
        a[param[i].index] = param[i].value;
    }
    return a;
}

var myArray = indexArray([
    { index: 123456, value : "bananas" },
    { index: 12, value : "grapes" },
    { index: 564, value : "monkeys" }
]);
SReject
  • 3,774
  • 1
  • 25
  • 41
2
var array1 = []
array1[23454] = 2

Just doing this should be fine. There's no set array size for javascript in the way there is for java.

If you really want to do this all in a single statement, you can make an object instead like this:

var object1 = {
    "23454":2,
    "123":1,
    "50":3
};

and then retrieve the numbers like this:

object1["23454"]  //2

I don't really recommend this though. The array method is a cleaner way of doing it even if it takes multiple lines since it doesn't require string conversion. I don't know enough about how these are implemented in browsers to comment on the performance impact.

Update

Since the 1 line requirement is based on something being passed to the server, I would recommend passing a JSON object to the server in the form:

"{"23454":2,"123":1,"50":3}"

then this code will parse it to an object:

var object1 = JSON.parse(jsonstringfromserver);

and if you like you can always convert that to an array by enumerating over the properties with a for in loop:

var array1 = []
for ( num in object1){
    array1[num] = object1[num];

That is probably unnecessary though since object1[123] will already return 1. You only need this if you plan on doing array specific operations.

Community
  • 1
  • 1
Ben McCormick
  • 25,260
  • 12
  • 52
  • 71
  • ok what i'm trying to do is initialize the array with multiple such items using a single statement. – Rajat Gupta Oct 25 '12 at 16:21
  • As I said in my answer, this isn't possible – SReject Oct 25 '12 at 16:22
  • @user01 SReject is right that this isn't possible with arrays, but you can do it using object notation as above. I would highly recommend sticking with array notation over multiple statements though – Ben McCormick Oct 25 '12 at 16:27
  • 1
    @ben336: not yet I'm somehow restricted to initialize the array as a single statement since a dynamically prepared array initialization string is appended from server side like this: `var array = `. Btw I'll accept an answer as soon as I reach a solution. – Rajat Gupta Oct 25 '12 at 17:00
  • @user01 in that case why don't you pass a JSON object from the server? You can then use JSON.parse() to convert it to an object, and if you wish then transform that to an array. I'll edit my answer to reflect this – Ben McCormick Oct 25 '12 at 17:04
  • @ben336: this json object would be just the same as javascript object you previously desribed, right ? – Rajat Gupta Oct 25 '12 at 17:22
  • @user01 correct, you could pass it as a string though. If you wanted array operations you could always convert it to an array once it was in the code. See the update to my answer above. – Ben McCormick Oct 25 '12 at 17:24
  • 1
    `var object1 = {23454:2, 123:1, 50:3};` is perfectly valid and all property names are stored as strings internally anyways. Accessing `object1[23454]` works fine too. – Felix Kling Oct 25 '12 at 17:36
2

You don't have to pre-define the size of an array before you assign to it. For example:

var _array = [];
    _array[0] = "foo";
    _array[1000] = "bar"; // _array.length => 1001 

_array[1] //undefined

No need to initialise the appropriate number of array elements before you assign to them.

Update

It already has been pointed out that you can use an object rather than an array. However, if you want to take advantage of array methods then this is still possible. Let me give you an example:

var obj = {
    0: 15,
    1: 10,
    2: 5,
    length: 3
};

If the object contains a length property then it can be treated as an array-like object. Although you can't call array methods directly from these objects you can use array methods.

Array.prototype.join.call( obj ); // 15,10,5

In fact using the ECMAScript 5 map function you can easily convert the above object to an array.

var _array = Array.prototype.map.call( obj, function( x ) { return x; } );

The map function does not exist in all browsers but you can use the following function if it doesn't.

Array.map = Array.map || function(a, f, thisArg) {
    return Array.prototype.map.call(a, f, thisArg); 
}
Bruno
  • 5,772
  • 1
  • 26
  • 43
0

You can do what you want with an Object in this way:

var o = {23454: 'aaaa', 23473: 'bbb'};

You will lose the array methods/fields, e.g. length, but you will gain what you said you are looking for, and you will be able to add/remove members easily.

Gal Talmor
  • 1,004
  • 9
  • 14
  • 1
    object item names can't start with numbers. you'd have to convert to string, which the OP has stated he/she wishes to avoid – SReject Oct 25 '12 at 16:31
  • 2
    @SReject: Sure they can. See also http://stackoverflow.com/questions/9367572/rules-for-unquoted-javascript-object-literal-keys. – Felix Kling Oct 25 '12 at 17:32