-1

I have an array like below

  arr=[];
  arr[0]={"zero": "apple"};
  arr[1]={"one": "orange"};
  arr["fancy"]="what?";

but i am getting length as 2 when i do console.log(arr.length) even though i am able to console all the values . and not able to get all values while doing console.log(JSON.stringify(arr)) What is the issue here.

here is the link to fiddle fiddle

NIsham Mahsin
  • 340
  • 5
  • 18
  • 1
    you expect `arr["fancy"]="what?";` to be part of the length? – epascarello Nov 20 '18 at 19:32
  • 1
    [MDN Array Length](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) documentation – pmkro Nov 20 '18 at 19:33
  • 1
    https://stackoverflow.com/questions/10563251/length-of-a-javascript-associative-array – epascarello Nov 20 '18 at 19:33
  • all arrays of course have a `length` property (which is what youf question is all about), so by the logic you apparently expect, `[].length` should be `1` (since it has a `length` property). Generally it's not a good idea to add string keys to an array - but if you do need to use them, then no, they don't affect the automatically-updated `length` property. – Robin Zigmond Nov 20 '18 at 19:36
  • not able to get all values while doing console.log(JSON.stringify(arr)) – NIsham Mahsin Nov 20 '18 at 19:40
  • @NIshamMahsin - no, you wouldn't be able to, since `JSON.stringify` when applied to an array assumes you're only after the numerically-indexed properties. What actually are you trying to do? What is the use case here? – Robin Zigmond Nov 20 '18 at 19:46

3 Answers3

2

.length is a special property in Javascript arrays, which is defined as "the biggest numeric index in the array plus one" (or 2^32-1, whatever comes first). It's not "the number of elements", as the name might suggest.

When you iterate an array, either directly with for..of or map, or indirectly with e.g. JSON.stringify, JS just loops over all numbers from 0 to length - 1, and, if there's a property under this number, outputs/returns it. It doesn't look into other properties.

georg
  • 211,518
  • 52
  • 313
  • 390
0

The length property don't work as one will expect on arrays that are hashtables or associative arrays. This property only works as one will expect on numeric indexed arrays (and normalized, i.e, without holes). But there exists a way for get the length of an associative array, first you have to get the list of keys from the associative array using Object.keys(arr) and then you can use the length property over this list (that is a normalized indexed array). Like on the next example:

arr=[];
arr[0]={"zero": "apple"};
arr[1]={"one": "orange"};
arr["fancy"]="what?";

console.log(Object.keys(arr).length);

And about this next question:

not able to get all values while doing console.log(JSON.stringify(arr))

Your arr element don't have the correct format to be a JSON. If you want it to be a JSON check the syntax on the next example:

jsonObj = {};
jsonObj[0] = {"zero": "apple"};
jsonObj[1] = {"one": "orange"};
jsonObj["fancy"] = "what?";

console.log(Object.keys(jsonObj).length);
console.log(JSON.stringify(jsonObj));
Shidersz
  • 16,846
  • 2
  • 23
  • 48
-1

From MDN description on arrays, here, "Arrays cannot use strings as element indexes (as in an associative array) but must use integers."

In other words, this is not Javascript array syntax arr["fancy"]="what?";

Which leads to the error in .length.

Dave P
  • 145
  • 8
  • Don't know who wrote that paragraph on MDN, but that's just silly. MDN is just a wiki, not an authoritative source, you need to double-check everything you read there. – georg Nov 20 '18 at 20:07
  • @georg, please read the accepted answer from this related question [link](https://stackoverflow.com/questions/9526860/why-does-a-string-index-in-a-javascript-array-not-increase-the-length-size). Maybe there is a confusion between associative array and array. Also reference [this](https://www.w3schools.com/js/js_arrays.asp), under the section _arrays are objects_. – Dave P Nov 20 '18 at 20:50
  • Yep, the same confusion over there as well. There's no dedicated "data storage" in an array, and you can perfectly assign string properties to it. In fact, all array properties are string ones, even if they look like integer numbers. – georg Nov 20 '18 at 21:00
  • @georg ,.. and as noted [here](https://www.thecodeship.com/web-development/common-pitfalls-when-working-with-javascript-arrays/), under the section _The associative array confusion_, `var myAssocArray = []; myAssocArray["foo"] = "bar";` "The above example is an abused array object. The above code works simply because arrays are objects too." – Dave P Nov 20 '18 at 21:14
  • I'd suggest that instead of random internet posts you read the authoritative source, the ECMA standard, which says pretty clearly what arrays are and what they are not. Here's the link: http://www.ecma-international.org/ecma-262/9.0/index.html#sec-array-objects. Have fun! – georg Nov 20 '18 at 21:26
  • @georg....numerous times in the ECMA documentation, "this value is an object that has a fixed length and whose **integer-indexed** properties are not sparse," seen at 22.2.3.25, 22.2.3.22, 22.2.3.21, 22.2.3.20....Now let's have the documentation define **integer-index**; "an integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 253-1. _An array index is an integer index whose numeric value i is in the range +0 ≤ i < 232-1._" ... – Dave P Nov 20 '18 at 22:02
  • TypedArray != Array, they are totally different things. – georg Nov 20 '18 at 23:26
  • @georg, 22.1 **Array Objects**: Array objects are exotic objects that give special treatment to a certain class of property names. See 9.4.2 for a definition of this special treatment. ...Section 9.4.2: An Array object is an exotic object that gives special treatment to **array index** property keys (see 6.1.7)....Now to the definition of array index: " An array index is an **integer index** whose numeric value i is in the range +0 ≤ i < 232-1."... – Dave P Nov 21 '18 at 00:07