InArray returning -1 with matching value - javascript

var x = new Array(10);
$.inArray(10,x);
#Returns -1
Fiddle
I've come across this weird issue, checking a value in an array with $.inArray, really simple.
But, if the array only has one value in it, inArray returns -1.
If I add another value to the array, it works as expected.
This only happens with integers and not with strings.
What's going on?!

If you want to create an array with the one number(10) inside you should use bracket literal:
var x = [10];
$.inArray(10,x);
Or with push:
var x = new Array();
x.push(10);
Obviously the first one is more readable and faster to write.
A JavaScript array is initialized with the given elements, except in the case where a single argument is passed to the Array constructor and that argument is a number. Note that this special case only applies to JavaScript arrays created with the Array constructor, not with array literals created with the bracket syntax.
If the only argument passed to the Array constructor is an integer, a new, empty JavaScript array and its length is set to that number
MDN
Fixed fiddle

I suggest to check documentation for arrays in JavaScript, link: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
In your case, by using:
var x = new Array(10);
It creates an array with length 10 and each item of the array is undefined
I suggest to use:
var x = [10];
this is an array with one item at index 0 that has value 10.

var x = new Array(10); creates an array with 10 slots, not an array that contains "10"

Related

creating new Array() constructor with number and string

Actually, I am working on someone others code.
While resolving a bug I found
such types of things.
Note: API is giving productNumber in number type.
Sometimes passing only one productNumber in new Array(). then a new
bug occurs.
And when entering productNumber more than one then working fine.
Why arr1[0] is giving undefined.
var productNumber1 = 1001;
var arr1 = new Array(productNumber1);
console.log("arr1",arr1[0]);
var productNumber2 = '1001';
var arr2 = new Array(productNumber2);
console.log("arr2",arr2[0]);
Could you please someone explain this behavior.
In case1 the argument you passing getting treated as a length of the array
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
A JavaScript array is initialized with the given elements, except in the case where a single argument is passed to the Array constructor and that argument is a number (see the arrayLength parameter below). Note that this special case only applies to JavaScript arrays created with the Array constructor, not array literals created with the bracket syntax.
arrayLength
If the only argument passed to the Array constructor is an integer between 0 and 2^32-1 (inclusive), this returns a new JavaScript array with its length property set to that number (Note: this implies an array of arrayLength empty slots, not slots with actual undefined values). If the argument is any other number, a RangeError exception is thrown.
So actually in case1, you are creating an array with length 1001.
However in case 2, that is getting treated as an element since it's not a number.
This is described in the documentation for the Array constructor:
If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with its length property set to that number
So if you pass a number like 1001 you'll set the length, but if you pass a string like '1001', you'll set the first value, and if you pass multiple arguments you will set multiple values.
Just don't use the Array constructor. Use the square bracket literal notation instead. That avoids the problem.
var productNumber1 = 1001;
var arr1 = [productNumber1];
console.log("arr1",arr1[0]);
var productNumber2 = '1001';
var arr2 = [productNumber2];
console.log("arr2",arr2[0]);
You may also use the Array.of() tool for this job.
var p1 = 1001,
p2 = "1001",
a1 = Array.of(p1),
a2 = Array.of(p2);
console.log(a1);
console.log(a2);

Javascript syntax: var array = [].push(foo);

Where foo is a defined variable, why is it that the following code:
var array = [].push(foo);
when outputted, equals 1?
From my tests, outputting array will simply output the length of the array.
So the code:
var array = [10,20].push(foo);
would give a value of 3.
As a related question (and to clarify what my code intended to do), why does this not intuitively do what it appears to do, ie:
var array = [];
array.push(foo);
where outputting array gives the expected result of [foo]?
When you use push method it returns length of array. So when you do:
var array = [10,20].push(foo);
you get [10, 20, foo] length of this array is three. But as you say var array it stores returned length from push method in this variable.
Array.prototype.push() always returns the new number of elements in the array. It does not return this instance or a new Array instance. push() is a mutator actually changes the contents of the array.
instead you can try
var array, foo = 30;
(array = [10,20]).push(foo);
console.log(array)
push is a function and it returns an integer representing the length of the array.
Imagine the definition of this function as
int push(object obj);
When you do this:
var array = [].push(foo);
You are actually running the function and returning the value.
Because the return value of push is the new length of the array Documentation and examples.
In your second example, you cited outputting the array, which is going to give you the new array in both cases. However, the returned result of your second case is the new array length as well
var array = [];
array.push(foo); //If you do this in the console, you'll see that 1 gets returned.
console.log(array); //While this will print out the actual contents of array, ie. foo
The definition of push() method including two parts in javascript: Part 1: it adds one or more elements to the end of an array, part 2: it returns the new length of the array.
I think you are missing the part 2 in your understanding of this method.

jQuery inArray() returns -1 if array contains single element

jQuery inArray returns -1 if the array contains single element.
var a = Array(1);
console.log($.inArray(1,a));
This returns -1. But if the array contains 2 or more elements it works perfectly.
var a = Array(1,2,3);
console.log($.inArray(1,a));
Returns perfect position.
Contrary to what you seem to think, Array(1) doesn't create an array with element 1 but an array of size 1. That's a specific behavior you get when you pass only one argument and it's an integer.
From the MDN :
If the only argument passed to the Array constructor is an integer
between 0 and 2^32-1 (inclusive), this returns a new JavaScript array
with length set to that number.
You should probably almost never use this Array constructor whose strange behavior leads to many bugs and which is mostly useless. Use this :
var a = [1];

Javascript array best practice to use [] instead of new array?

I read at many tutorials that the current best practices to create a new javascript array is to use
var arr = []
instead of
var arr = new Array()
What's the reasoning behind that?
It might be because the Array object can be overwritten in JavaScript but the array literal notation cannot. See this answer for an example
Also note that doing:
var x = [5];
Is different than doing:
var x = new Array(5);
The former creates an initializes an array with one element with value of 5. The later creates an initializes an array with 5 undefined elements.
It's less typing, which in my book always wins :-)
Once I fixed a weird bug on one of our pages. The page wanted to create a list of numeric database keys as a Javascript array. The keys were always large integers (a high bit was always set as an indicator). The original code looked like:
var ids = new Array(${the.list});
Well, guess what happened when the list had only one value in it?
var ids = new Array(200010123);
which means, "create an array and initialize it so that there are 200 million empty entries".
Usually an array literal(var a=[1,2,3] or a=[]) is the way to go.
But once in a while you need an array where the length itself is the defining feature of the array.
var A=Array(n) would (using a literal) need two expressions-
var A=[]; A.length=n;
In any event, you do not need the 'new' operator with the Array constructor,
not in the way that you DO need 'new' with a new Date object, say.
To create Array without Length
var arr = [];
To create Array with Length more dynamically
var arr;
( arr = [] ).length = 10; // 10 is array length
To create Array with Length less dynamically
var arr = [];
arr.length = 10;

Javascript array length incorrect on array of objects

Could someone explain this (strange) behavior? Why is the length in the first example 3 and not 2, and most importantly, why is the length in the second example 0? As long as the keys are numerical, length works. When they are not, length is 0. How can I get the correct length from the second example? Thank you.
a = [];
a["1"] = {"string1":"string","string2":"string"};
a["2"] = {"string1":"string","string2":"string"};
alert(a.length); // returns 3
b = [];
b["key1"] = {"string1":"string","string2":"string"};
b["key2"] = {"string1":"string","string2":"string"};
alert(b.length); // returns 0
One thing to note is that there is a difference between regular arrays and associative arrays. In regular arrays (real arrays), the index has to be an integer. On the other hand, associative arrays can use strings as an index. You can think of associative arrays as a map if you like. Now, also note, true arrays always start from zero. Thus in your example, you created an array in the following manner:
a = [];
a["1"] = {"string1":"string","string2":"string"};
a["2"] = {"string1":"string","string2":"string"}
Javascript was able to convert your string indexes into numbers, hence, your code above becomes:
a = [];
a[1] = {"blah"};
a[2] = {"blah"};
But remember what i said earlier: True arrays start from zero. Therefore, the javascript interpreter automatically assigned a[0] to the undefined. Try it out in either firebug or the chrome/safari console, and you will see something like this when you try to print "a". You should get something like "[undefined, Object, Object]. Hence the size 3 not 2 as you expected.
In your second example, i am pretty sure you are trying to simulate the use of an associated array, which essentially is adding properties to an object. Remember associated arrays enable you to use strings as a key. So in other terms, you are adding a property to the object. So in your example:
b["key1"] = {"string1":"string","string2":"string"};
this really means:
b.key1 = {"string1":"string","string2":"string"};
Initializing b =[] simply creates an array, but your assignment doesn't populate the array. It simply gives "b" extra properties.
length returns 1 + the largest integer key in the object.
In a the largest key is 2 so 1+2 is 3.
In b there are no integer keys (the keys there are key1 and key2 which cannot be converted into ints) so Javascript assumes that the largest key is -1, and 1 + -1 yields 0.
This program will help you see that:
a = [];
a["1"] = {};
a["4"] = {};
alert(a.length); // Prints 5
From the ECMAScript standard, ECMA-262, 5th ed.
15.4.5.2 length
The length property of this Array object is a data property whose value is always numerically greater than the name of every deletable property whose name is an array index.
Note the length property of an array only takes into account array indices, which are integers; setting other properties doesn't affect length.
For an array, a["3"] is equivalent to a[3] (this behavior is specified by ยง 15.4.5.1); 3 is an array index rather than a property. Thus setting a["3"] affects the array's length. b["key1"] is equivalent to b.key1. Setting properties don't affect the length of a collection.

Categories