In the example below, the array2.length is only 10, while in my mind, it should be 13.
Why does the "string keyed" indexes not increase the length of the array?
I can store things and still access it, and the VS debugger shows that those arrays are being stored properly. So why is the length not increased?
var array2 = new Array();
array2["a"] = new Array();
array2["b"] = new Array();
array2["c"] = new Array();
for (var i = 0; i < 10; ++i)
array2[i] = new Array();
var nothing = "";
for (var i = 0; i < array2.length; ++i)
nothing = "";
Javascript arrays cannot have "string indexes". A Javascript Array is exclusively numerically indexed. When you set a "string index", you're setting a property of the object. These are equivalent:
array.a = 'foo';
array['a'] = 'foo';
Those properties are not part of the "data storage" of the array.
If you want "associative arrays", you need to use an object:
var obj = {};
obj['a'] = 'foo';
Maybe the simplest visualization is using the literal notation instead of new Array:
// numerically indexed Array
var array = ['foo', 'bar', 'baz'];
// associative Object
var dict = { foo : 42, bar : 'baz' };
Because the length is defined to be one plus the largest numeric index in the array.
var xs = [];
xs[10] = 17;
console.log( xs.length ); //11
For this reason, you should only use arrays for storing things indexed by numbers, using plain objects instead if you want to use strings as keys. Also, as a sidenote, it is a better practice to use literals like [] or {} instead of new Array and new Object.
You're not adding items to the array; you're adding properties to the Array object.
As said above, use object for associative arrays.
If you don't you won't necessarily notice you're doing it wrong, until you innocently use "length" as an array index :
var myArray = [];
myArray["foo"] = "bar"; //works
console.log(myArray["foo"]) //print "bar"
myArray["length"] = "baz" //crash with a "RangeError: Invalid array length"
That is because you are replacing the length attribute of an array with a String, which is invalid.
"string keyed" indexes are not indexes at all, but properties. array2["a"] is the same as saying array2.a. Remember that you can set properties on any kind of variable in javascript, which is exactly what you're doing here.
You can push object to array, it will automatically get indexed (integer). If you want to add index as you want then you want to make it as object
If you want to use an object's properties as if they were like instances of a string indexed array, the work around for the length is:
var myArray = new Array();
myArray["a"] = 'foo';
myArray["b"] = 'bar';
myArray["c"] = 'baz';
let theLength = Object.keys(myArray).length
Related
In the example below, the array2.length is only 10, while in my mind, it should be 13.
Why does the "string keyed" indexes not increase the length of the array?
I can store things and still access it, and the VS debugger shows that those arrays are being stored properly. So why is the length not increased?
var array2 = new Array();
array2["a"] = new Array();
array2["b"] = new Array();
array2["c"] = new Array();
for (var i = 0; i < 10; ++i)
array2[i] = new Array();
var nothing = "";
for (var i = 0; i < array2.length; ++i)
nothing = "";
Javascript arrays cannot have "string indexes". A Javascript Array is exclusively numerically indexed. When you set a "string index", you're setting a property of the object. These are equivalent:
array.a = 'foo';
array['a'] = 'foo';
Those properties are not part of the "data storage" of the array.
If you want "associative arrays", you need to use an object:
var obj = {};
obj['a'] = 'foo';
Maybe the simplest visualization is using the literal notation instead of new Array:
// numerically indexed Array
var array = ['foo', 'bar', 'baz'];
// associative Object
var dict = { foo : 42, bar : 'baz' };
Because the length is defined to be one plus the largest numeric index in the array.
var xs = [];
xs[10] = 17;
console.log( xs.length ); //11
For this reason, you should only use arrays for storing things indexed by numbers, using plain objects instead if you want to use strings as keys. Also, as a sidenote, it is a better practice to use literals like [] or {} instead of new Array and new Object.
You're not adding items to the array; you're adding properties to the Array object.
As said above, use object for associative arrays.
If you don't you won't necessarily notice you're doing it wrong, until you innocently use "length" as an array index :
var myArray = [];
myArray["foo"] = "bar"; //works
console.log(myArray["foo"]) //print "bar"
myArray["length"] = "baz" //crash with a "RangeError: Invalid array length"
That is because you are replacing the length attribute of an array with a String, which is invalid.
"string keyed" indexes are not indexes at all, but properties. array2["a"] is the same as saying array2.a. Remember that you can set properties on any kind of variable in javascript, which is exactly what you're doing here.
You can push object to array, it will automatically get indexed (integer). If you want to add index as you want then you want to make it as object
If you want to use an object's properties as if they were like instances of a string indexed array, the work around for the length is:
var myArray = new Array();
myArray["a"] = 'foo';
myArray["b"] = 'bar';
myArray["c"] = 'baz';
let theLength = Object.keys(myArray).length
I have a code :
var index = 100;
var arr =[];
arr[index.toString()] = "Hello"
The result : index still known as integer not a string. Anyone can explain what's wrong with my code?
You have to declare associative arrays using {}, which creates a new object, because in JavaScript, arrays always use numbered indexes.
You need to declare an object: var arr={};
arrays use numbered indexes.
objects use named indexes.
var index = 100;
var arr ={};
arr[index.toString()] = "Hello";
console.log(arr);
How to make associative array with number as string in Javascript
JavaScript doesn't have associative arrays in the sense that term is frequently used. It has objects, and as of ES2015 (aka "ES6"), it has Maps.
The result : index still known as integer not a string. Anyone can explain what's wrong with my code?
The index variable's value is still a number, yes, because you haven't done anything to change it. But the index in the array is a string (and would be even if you didn't use .toString()), because standard arrays aren't really arrays at all1, they're objects with special handling of a class of properties (ones whose names are strings that fit the spec's definition of an array index), a special length property, and that use Array.prototype as their prototype.
Here's proof that array indexes are strings:
var a = [];
a[0] = "zero";
for (var name in a) {
console.log("name == " + name + ", typeof name == " + typeof name);
}
That said, you don't want to use an array when you want a generic object or map.
Here's using a generic object for name/value mappings:
var o = Object.create(null);
var name = "answer";
o[name] = 42;
console.log(o[name]); // 42
The property names in objects are strings or (as of ES2015) Symbols. I used Object.create(null) to create the object so it wouldn't have Object.prototype as its prototype, since that gives us properties (toString, valueOf, etc.) that we don't want if we're using the object as a map.
Here's using a Map:
var m = new Map();
var name = "answer";
m.set(name, 42);
console.log(m.get(name)); // 42
The main advantages Maps have over objects are:
Their keys can be anything, not just strings or Symbols
They're iterable, so you can use for-of to loop through the mappings they contain
Maps have a size property telling you how many entries they have
Maps guarantee that iteration of their entries is performed in the order the entries were added to the map
With ES6, you could use a Map, which holds any type as key.
var map = new Map;
map.set(100, "Hello");
map.set('100', "Foo");
console.log(map.get(100)); // 'Hello'
console.log(map.get('100')); // 'Foo'
console.log([...map]);
JavaScript does not support arrays with named indexes, in JavaScript, arrays always use numbered indexes.
If you use a named index, JavaScript will redefine the array to a standard object.
After that, all array methods and properties will produce incorrect results.
As you can see in the following example:
var person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
var x = person.length; // person.length will return 0
console.log(x);
var y = person[0]; // person[0] will return undefined
console.log(y);
I have this example work fine with chrome and firefox
var array = [];
array.a = 1;
array.b = 2;
console.log(array)
in chrome and firefox return a
objectArray [ a:1 b:2 ]
but IE return objectArray[] lenght 0
any idea?
{} creates an empty literal object (= key-value object). equal to new Object()
[] creates an empty array. equal to new Array()
Example:
var obj = {};
obj.a = 1; //add a key-value
console.log(obj);
var array = [];
array.push(2); // add a value
console.log(array);
In JavaScript arrays are also Objects and the following statements does not cause error and are still valid:
var array = [];
array.a = 1;
I don't know how your code can works on Chrome. You initialize a variable but you modify another variable.
Anyway, you want to make an Object and not an Array.
Try with this code :
var test = {};
test.a = 1;
test.b = 2;
console.log(test)
But in IE, you'll maybe get [object Object] in your output. It's because IE doesn't know how to print an object correctly.
Arrays are arrays ([]) and associative arrays are plain objects ({}) in JavaScript.
Use the following instead:
var array = {};
array.a = 1;
array.b = 2;
console.log(array);
And beware that objects do not return amount of properties in length. Instead you may use Object.keys(array).length or do count them with for loop.
JavaScript doesn't have associative arrays. In JavaScript everything is an object including arrays, which are instances of an Array object and just like with any other object you can add properties to them:
var test = [];
test.a = 3;
test['b'] = 4;
test[3] = 6;
test['4'] = 6;
So basically, elements of an array are actually properties of an Array object, but not all properties can be considered elements. According to the ECMAScript Language Specification (15.4 Array Objects) a property is an element only if it's name meets the following criteria:
A property name P (in the form of a String value) is an array index if
and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not
equal to 232 - 1.
This is important because the length property, as well as methods such as forEach, take into account only properties which meet this criteria.
ECMAScript 6, however, will support Maps:
var myMap = new Map();
var keyObj = {},
keyFunc = function () {},
keyString = "string";
myMap.set(keyString, "value associated with keyString");
myMap.set(keyObj, "value associated with keyObj");
myMap.set(keyFunc, "value associated with keyFunc");
myMap.size; // 3
myMap.get(keyString); // "value associated with keyString"
myMap.get(keyObj); // "value associated with keyObj"
myMap.get(keyFunc); // "value associated with keyFunc"
A naive confusion:
var arr1 = new Array();
var arr2 = Object.create(Array.prototype);
//Inserting elements in "both arrays"
arr1[0] =0;
arr1[9] =9;
arr2[0] =0;
arr2[9] =9;
arr1.push(10);
arr2.push(10);
console.log(arr1.length); // prints 11
console.log(arr2.length); // prints 1
Both objects inherits Array.prototype, but they behave differently with the [] operator. Why?
In the first case you create an array object that maintains the length property when you access a integer, non-negative property (index).
In the second case you created a regular object that inherits the Array prototype. Using [] on that object is the same as any object and simply sets regular properties on it.
var arr1 = new Array(); // or var arr1 = [];
arr1[0] = 0;
arr1['foo'] = 3;
// arr1 has a length of 1 because 0 is an array index and 'foo' is a regular property.
var arr2 = Object.create(Array.prototype);
arr2[0] = 0;
arr2['foo'] = 3;
// arr2 has a length of 0 because both 0 and 'foo' are regular properties.
The ECMAScript 5 Language Spec describes how length is maintained in section 15.4.
Array objects give special treatment to a certain class of property
names. A property name P (in the form of a String value) is an array index if and only if ToString(ToUint32(P)) is equal to P and
ToUint32(P) is not equal to 2^(32−1).
[...]
Specifically, whenever a
property is added whose name is an array index, the length property is
changed, if necessary, to be one more than the numeric value of that
array index;
var arr1 = new Array(); is the proper way to instantiate an array. It is the same as using the array literal: var arr1 = [];
How do I create an empty 2D array in Javascript (without knowing how many rows or columns there will be in the new array)?
If it's a simple array var newArray = new Array(); I can assign as many elements as I want. But what about a 2D array? Can I create one without specifying the numbers of rows and columns? and how do I access the elements afterwards (myArray[0][1] or myArray[0,1])?
You can create a 6 x 6 empty array like this:
var myGrid = [...Array(6)].map(e => Array(6));
Array(6) generates an array with length = 6 and full of undefined values.
We map that array to another array full of undefined values.
In the end, we get a 6x6 grid full of undefined positions.
If you need to initialize the grid with a default value:
var value = 'foo'; // by default
var myGrid = [...Array(6)].map(e => Array(6).fill(value));
Now you have a 6 x 6 grid full of 'foo'.
Yes you can create an empty array and then push data into it. There is no need to define the length first in JavaScript. Check out jsFiddle Live Demo
Define:
const arr = [[],[]];
Push data:
arr[0][2] = 'Hi Mr.A';
arr[1][3] = 'Hi Mr.B';
Read data:
alert(arr[0][2]);
alert(arr[1][3]);
Update:
Here is also a video recommended by Brady Dowling:
Create a 2D array: ([https://www.youtube.com/watch?v=tMeDkp1J2OM][2])
There are no two dimensional arrays in Javascript.
To accomplish the effect of a two dimensional array, you use an array of arrays, also known as a jagged array (because the inner arrays can have different length).
An empty jagged array is created just like any other empty array:
var myArray = new Array();
You can also use an empty array literal:
var myArray = [];
To put any items in the jagged array, you first have to put inner arrays in it, for example like this:
myArray.push([]);
myArray[0][0] = 'hello';
You can also create an array that contains a number of empty arrays from start:
var myArray = [[],[],[]];
That gives you a jagged array without any items, but which is prepared with three inner arrays.
As it's an array of arrays, you access the items using myArray[0][1].
Say you wanted to make a 2d array (i.e. matrix) that's 100x100, you can do it in one line, like this:
var 2darray = new Array(100).fill(null).map(()=>new Array(100).fill(null));
This will create a 100x100 matrix of NULL's.
Replace the 100x100 with whatever dimensions you want, and the null's with whatever is your prefered default value, or blank for undefined.
You can use a simple for loop to create an array of the approximate size and then push more rows if need be.
const arr = [];
const n = 7;
const m = 5;
for (let i = 0; i < n; i++) {
arr.push(new Array(m).fill(0));
}
const arr = [];
const n = 7;
const m = 5;
for (let i = 0; i < n; i++) {
arr.push(new Array(m).fill(0));
}
console.log(arr);
var myArray = [
["cats","dogs","monkeys","horses"],
["apples","oranges","pears","bananas"]
];
document.write(myArray[0][2]) //returns "monkeys"
Two things:
1) The array length property improperly reports the array length if called after the var myArray = [[],[]]; statement. Technically, since the empty arrays are defined, they are getting counted by the length property, but in the spirit of the length property it really should return 0, because no non-empty elements have been added to any of the arrays.
A minimum work around is to use two nested for( in ) loops, one for the 1st array and one for the 2nd array, and to count the non-undefined elements.
2) Extending Siamak A.Motlagh example and adding a arr([2][4]) = 'Hi Mr.C'; assignment fails with an "Uncaught TypeError: Cannot set property '4' of undefined" error.
See the jsFiddle: http://jsfiddle.net/howardb1/zq8oL2ds/
Here is a copy of that code:
var arr = [[],[]];
alert( arr.length ); // wrong!
var c = 0;
for( var i in arr )
for( var j in arr[ i ] )
if( arr[ i ][ j ] != undefined )
++c;
alert( c ); // correct
arr[0][2] = 'Hi Mr.A';
alert(arr[0][2]);
arr[1][3] = 'Hi Mr.B';
alert(arr[1][3]);
arr[2][4] = 'Hi Mr.C'; // At this point I'm getting VM558:62 Uncaught TypeError: Cannot set property '4' of undefined
alert(arr[2][4]);
var c = 0;
for( var i in arr )
for( var j in arr[ i ] )
if( arr[ i ][ j ] != undefined )
++c;
alert( c );
Why does the third assignment fail? What about the [[],[]] creation statement told it that the first array was valid for 0 and 1, but not 2 or that 2 and 3 were ok for the second array, but not 4?
Most importantly, how would I define an Array in an Array that could hold date objects in the first and second arrays. I'm using the jQuery-UI DatePicker, which expects an array of dates, as in date objects, which I've extended to use a second date array to contain date objects that contain times so I can keep track of multiple dates, and multiple times per day.
Thanks.
The functions I use
function get_empty_2d_array(numRows, numColumnns) {
return [...Array(numRows)].map(e => Array(numColumnns));
}
function get_2d_array_filled(numRows, numColumnns, fillValue) {
return [...Array(numRows)].map(e => Array(numColumnns).fill(fillValue));
}
This also works as an expression:
var twoDarr= new Array(desiredLength);
for (i=0;i<twoDarr.length;i++) {twoDarr[i]=[];}
I don't know how it pars in terms of performance with the rest of the answers here, if you have a clue let me know in the comments.
If you don't know the length of the array beforehand pls have in mind that you can use either push([]), or splice() if you want to push/remove/replace a new element in place of an existing one.
const grid = new Array(n).fill(new Array(n))