JavaScript, array A length is 0 but A[key] has value - javascript

Here is the code
var A = [];
A['key1'] = 'apple';
console.log(A.length);
console.log(A['key1']);
A.length is 0 in the log.... But I just don't get it, apparently A['key1'] has a value 'apple'. Why A.length is 0?

Your are define A is array .Array is not key and value pair,Object only have key value pair
Check the console.log A its still empty
var A = [];
A['key1'] = 'apple';//its not added because is a array
console.log(A);
console.log(A.length);
If you need to add key value pair Define A as a Object.and find the length using Object.keys(A) .It will create array of the Object keys
var A = {};
A['key1'] = 'apple';
console.log(A);
console.log(Object.keys(A).length);
console.log(A.key1.length)
Better see the Difference between an array and an object?

You are using javascript associative array which don't have the built-in function like length to get the number of properties in the array. So Instead of using length function you can use the following line to get the number of properties in the array.
Object.keys(A).length

Related

JSON stringify does not convert array [duplicate]

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

Can't create JS object with array indices as key & value?

Task: convert an array into an object with one key-value pair, where the first array item is the key, and the last array item is the value.
E.g., [1,2,3] should convert to {1: 3}
I can't get it to work as:
function transformFirstAndLast(array) {
var firstLast = {
array[0]: array[-1]
};
return firstLast
}
But only as:
function transformFirstAndLast(array) {
var firstLast = {};
firstLast[array[0]] = array[array.length - 1];
return firstLast
}
...why doesn't the first work? Why can't you index the array for the key & value?
You could pop the last element and take a computed property for the object. (For the first element, you could take Array#shift, if you like to do it in the same manner.)
function transformFirstAndLast(array) {
return { [array[0]]: array.pop() };
}
console.log(transformFirstAndLast([1, 2, 3]));
ES5 with a temporary variable.
function transformFirstAndLast(array) {
var temp = {};
temp[array[0]] = array.pop();
return temp;
}
console.log(transformFirstAndLast([1, 2, 3]));
Take the first is easy, take the last is the size minus one like this:
function firstAndLast(array) {
var ary = {};
ary[array[0]] = array[array.length - 1];
return ary;
}
console.log(firstAndLast([1,2,3]))
First, you must remember than an array is a type of JavaScript object and, in JavaScript, an object property (a.k.a. "key") can be accessed or assigned in two ways:
via "dot notation"
object.property = value;
via array syntax
object["property"] = value;
Next, remember that, in JavaScript, if you assign a value to a property that doesn't exist (using either syntax from above), the property will be created, like in the following:
console.log(window.someNewProperty); // undefined
window.someNewProperty = 17; // This causes the property to be created
window["someOtherNewProperty"] = "Voilla!"; // So does this, just with array syntax
console.log(window.someNewProperty); // 17
console.log(window["someOtherNewProperty"]); // "Voilla!"
Now, moving on to the specifics of an array, it's critical to understand the difference between an object property/key name (which is always represented as a string) and an array index (which is always a non-negative integer up to the max integer in JavaScript). So, if you have an array and seemingly assign a value to a negative index, you are actually creating a property that is named the negative index and not actually adding to the length of the array or making a new indexed position in the array. We can see that here:
var myArray = ["a", "b", "c"];
myArray[-1] = 15;
console.log(myArray.length); // 3 not 4
console.log(myArray[-1]); // 15
// Now to prove that -1 is a string name for a new property and not an index:
console.log(myArray); // Notice no 15 in the indexed values?
// And, if we enumerate the object (not just the indexes), we'll see that we actually created
// a property with [-1], not a new index.
for(var prop in myArray){
// Note that prop is not the value of the property, it's the property name itself
console.log(typeof prop, prop, myArray[prop]);
}
So, to sum up, Arrays have non-negative integer indexes to store the items that make up the length of the array, but Arrays are also objects and have properties, like all other objects do. Any bracket assignments that use anything other than non-negative integers as the key name will become new properties, not array indices.

How to remove all undefined keys from a javascript array (hopefully when creating the array?)

I have placed my frustrations into a jsfiddle to observe here: http://jsfiddle.net/8ShFr/1/
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
alert('why does this array have a length of ' + brand_new_array.length + '???');
I am doing some calculations client side that require me to set javascript array keys of 1M+ in number.
Not knowing exactly what that number is demands that I iterate through the first 1M+ empty array values before getting to an array key that holds data.
I simply want to set a single large key value for a javascript array without creating a bunch of empty keys before it?
I am using jQuery.each to iterate over the array, and it keeps going through array[0], array[1], array[2], etc... when I only set array[123125] for example.
Just filter out the undefineds.
brand_new_array = brand_new_array.filter(function(n){return n !== undefined});
The reason for the length being 10 is that an array's length is set to the largest index number in the array. However, this does not mean there are 9 other values in there because in javascript an array is at its base an object.
The length is just a property in the object. Arrays in javascript are at their core objects (Array Object 1). They merely act like arrays through an api.
"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" 1
1. ECMAScript Language Specification 15.4 Array Objects
You probably want to just use an object with strings for keys (the keys can be the toString() of Numbers, which will happen automatically if you try to use numbers).
var sparse_array_obj = {};
sparse_array_obj[10003210234] = 4; // Fair dice roll
sparse_array_obj[5] = 17; // Truly random number
sparse_array_obj[900] = Math.random(); // Pseudorandom number
for(var i in sparse_array_obj)
console.log(sparse_array_obj[i]);
The downside is that Javascript provides no guarantees about the iteration order through an object (since its keys are unordered by definition). There are however ways around this, such as:
// Sort the keys in numeric order
var sorted_keys = Object.keys(sparse_array_obj).sort(function(a, b){ return a - b; });
for(var i = 0; i < sorted_keys.length; i++)
console.log(sparse_array_obj[sorted_keys[i]]);
Object.keys needs to be shimmed in older browsers.
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
var result = brand_new_array.filter(function(e) { return e != undefined;})[0];
alert(brand_new_array.indexOf(result));
Travis J is right. The array in your example only contains one entry, but your use of jQuery.each() is making you think there are 10 entries because it iterates from 0 up to the highest index number of the array (defines the length). This is from the jQuery.each() API documentation.
A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.
Going back to your example:
var brand_new_array = new Array();
brand_new_array[10] = "random array value";
This will result in only one console.log output:
for(var i in brand_new_array)
console.log(brand_new_array[i]);
This will result in 10 console.log outputs:
$(brand_new_array).each( function(i,e) { console.log(e) })
Similarly, this will result in 10 console.log outputs:
for (var i=0;i<brand_new_array.length;i++)
console.log(brand_new_array[i]);
If you really want to stick with using .each() then you can skip the undefined indices like so:
$(brand_new_array).each( function(i,e) {
if (this.hasOwnProperty(i)){ console.log(e) }
})
Filter the falsy items - including undifined:
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]
The length is 11 because the index starts at 0.
x[0] = undefined
x[1] = undefined
x[2] = undefined
x[3] = undefined
x[4] = undefined
x[5] = undefined
x[6] = undefined
x[7] = undefined
x[8] = undefined
x[9] = undefined
x[10] = "random array value"

Difference between associative [],{} and object in javascript [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between an array and an object?
The item exists in the array but it says that the array is 0 length?
I m a bit confused in object and associative array in javascript. I read this :question but this question says that there is not much of a difference in both. I wrote this in the console:
var a = [];
a["A"] = 1;
var b = {};
b["B"] = 2;
var c = new Object();
c["C"] = 3;
output for above are as:
a gives {A : 1}
b gives {B : 2}
c gives {C : 3}
All above three cases gives same reault as in they all gives an object. Question is how all above 3 cases are treated in javascript.
An array is also an object, that's why you can use non-numeric indices also. Those will be added as properties to the array object, not part of the array data.
The difference between an array and an object, is that the array counts properties with a numeric index as being part of the array data, and updates the length property accordingly. (Also the Array object has some specific methods to work with the array data.)
var a = [];
a[42] = 1337;
Now the length has changed to include the item:
alert(a.length); // shows 43
Using strings or numbers as index doesn't matter, a numeric index counts even if it's a string:
alert(a[42]); // shows 1337
alert(a["42"]); // shows 1337
Reducing the length removes the properties outside it:
a.length = 10;
alert(a[42]); // shows undefined
In your example, b and c are essentially the same thing, because {} is the equivalent of new Object().
Coming back to a, it's defined as an Array which is a special kind of Object in the sense that numeric properties (based on uint32) are treated differently. Its length property gets updated when those properties are added and removed.
When you use 'A' as an index, it gets treated as a regular property, defined by how Object works with properties, so you can access it as a.A or a['A'] whereas an index of [5] can only be accessed using a[5].
Normally, the debug output of an array is always [] unless the length property is non-zero, so the output you've shown is somewhat irregular.
Trivia
According to the ECMAScript documentation, a particular value p can only be an array index if and only if:
(p >>> 0 === p) && (p >>> 0 !== Math.pow(2, 32) - 1)
See also:
The item exists in the array but it says that the array is 0 length?
Let's start by clarifying something:
new Object() is the same as {}
new Array() is the same as []
The latter are just shortened forms of the former.
Behind the scenes, everything in javascript is basically an object (this is an exaggeration but fairly accurate). Arrays are simply derived from objects. Here's a fairly rudimentary example of what an Array REALLY looks like:
var myArray = {};
myArray[0] = 'value1';
myArray[1] = 'value2';
myArray[2] = 'value3';
myArray[length] = 3;
The prototype of an array contains all the methods. For example:
// myArray#push
myArray.prototype.push = function(val){
myArray[this.length] = val;
this.length++;
}
Another way to illustrate this is to take an array and add keys that are not numeric:
var example = [];
example.push(0);
example.push(1);
example.push(2);
example['a'] = 'a';
example['b'] = 'b';
example['c'] = 'c';
example.log = function(){
for(var i = 0, l = this.length; i < l; i++){
console.log( example[i] );
}
console.log(this['a']);
console.log(this['b']);
console.log(this['c']);
}
// example[0] is 0
// example[1] is 1
// example[2] is 2
// example.log is my custom function
example.log(); // results in
// 0
// 1
// 2
// a
// b
// c
Also, don't always believe everything the console tells you. For example, if you do this:
var console_confusion = {};
console_confusion.length = 100;
console_confusion.splice = function(){ /* do absolutely nothing */ };
console.log( console_confusion );//results in
//
// in Chrome:
// [undefined × 100]
//
Chrome will interprut anything with a numeric length property and a splice function as an Array. This is why jQuery objects look like Arrays in the console.
Please read the following article – http://www.2ality.com/2012/12/arrays.html
In short, “regular arrays”, denoted as [] in JavaScript, are also objects, just like {}, but they have length property and “numeric” keys (“indicies”), plus their internal __proto__ property points at Array.prototype object, which holds all Array methods, such as push or forEach etc.
first is an array
second is an object array
third is an array object

Why does a string index in an array not increase the 'length'?

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

Categories