What is happening when adding a number to the array element - javascript

Example 1:
Var arr = [1,2,3] + 1;
console.log(arr) // "1,2,31"
typeof arr // String
Example 2:
var arr = 5 + ["h","e","l","l","o"];
console.log(arr) // "5h,e,l,l,o";
typeof arr // String
Doing the above concatenate the number/string to the last/first element in the array. Would like to understand what happens here?

While you are using + (concatenation in this case ), it's applying toString() method to the array. So it's just concatenating with the result and not appending with last or first element.
The Array object overrides the toString method of Object. For Array objects, the toString method joins the array and returns one string containing each array element separated by commas.
JavaScript calls the toString method automatically when an array is to be represented as a text value or when an array is referred to in a string concatenation. (Taken from here)
Check the following snippet all those are results the same.
var arr = [1, 2, 3];
// all these are providing the same result
// result of toString method
console.log(arr.toString())
// concatenation with empty string at end
console.log(arr + "")
// concatenation with empty string at start
console.log("" + arr);

To add an element to the array use one of this methods.
As #Pranav C Balan mentioned + operator try to concatenate 2 values. That's one of the most weird parts in Javascript. Here is a very helpful page with all of subtleties JS Garden
Example 1:
Var arr = [1,2,3];
arr.push(1)
console.log(arr) // [1,2,3,1]
typeof arr // object
Example 2:
var arr = ["h","e","l","l","o"];
arr.unshift(5);
console.log(arr) // [5,"h","e","l","l","o"];
typeof arr // object

Related

concatenate problems with concat function

In this case of concat() function, i don't get why the value of the length property is not concatenated to array. Also when i change the value of length property to some random value, the first two properties are ignored as well when i concatenate them.
1st case:
let arr = [1, 2];
let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: 2
};
alert( arr.concat(arrayLike) ); // 1,2,something,else
2nd case:
let arr = [1, 2];
let arrayLike = {
0: "something",
1: "else",
[Symbol.isConcatSpreadable]: true,
length: "random",
};
console.log( arr.concat(arrayLike) ); // 1,2
Your arrayLike object is sort of mimicking being an array like arr. So if you're treating it like a normal array, then why would you expect the value of length to be counted as a value in the array?
In your actual array, arr, you would have arr.length == 2. But 2 is not a value in the array, it just tells you how many values are in the array (two values, 1 and 2). This is how JavaScript knows how many values to look for. If you were to set arr.length = 1, suddenly JavaScript would only show one value instead of two. See here:
let arr = [1, 2];
console.log(arr); //[1, 2]
arr.length = 1;
console.log(arr) //[1]
Similarly, your length: 2 property in your arrayLike object is being used to represent an array with 2 elements. If you set it to something that isn't a number, JavaScript no longer knows how many values could be in the "array", so it apparently simply counts it as 0 - an empty array.

How does join() produce different results depending on the arguments?

I can't quite understand why the join() call below produces different results, depending on the type of argument(s) provided.
Here's what I found:
var test = function() {
var args = Array.prototype.join.call(arguments,"_");
return args
};
console.log(test([1,2,3])) // #1: returns 1,2,3
console.log(test(1,2,3)) // #2: returns 1_2_3
Given join(arguments, '_'), shouldn't it produce a _ delimited string in both tests above? Why does #1 return a comma delimited value instead?
When you pass an array to test, the arguments object becomes an array of arrays, not a plain array of plain values. It's the difference between
arguments = [[1,2,3]];
and
arguments = [1,2,3];
When you call .join on an array of arrays, each inner array gets implicitly coerced to a string first, resulting in '1,2,3' - the values of the inner arrays do not get .joined by the delimiter, only the immediate children of the outer array get .joined by the delimiter.
In your code, you only have one argument in the first example, that being an array. Joining a single element will remove the brackets:
var test = function() {
var args = Array.prototype.join.call(arguments,"_");
return args
};
console.log(test([1,2,3])) // args = [[1,2,3]]
console.log(test(1,2,3)) // args = [1,2,3]
console.log([[1,2,3]].join('_'))
console.log([1,2,3].join('_'))
Another way to look at this is to provide another array as an argument to test():
var test = function() {
var args = Array.prototype.join.call(arguments,"_");
return args
};
console.log(test([1,2,3], [4,5,6]))
In the first example you are not calling .join on the array but on arguments. That variable will be populated with an array-like object that has an array as first index, in essence, you are calling the equivalent of:
let myArguments = [[1, 2, 3]];
console.log(myArguments.join("_"));
instead of what you do (the equivalent of) in the second example:
let myArguments = [1, 2, 3];
console.log(myArguments.join("_"));
The first one, first argument is [1,2,3] which is joined with the second argument, which is nothing -> output is [1,2,3].toString().
Second call, it's actually joining all the 3 arguments, resulting in outputting 1_2_3.
Because you're passing one argument which is an array - so it converts it to a string, then attempts to join it to the other arguments (there are none) so it just returns the string.
var test = function() {
var args = Array.prototype.join.call(arguments, "_");
return args
};
console.log(test([1, 2, 3]));
console.log(test(1, 2, 3));
You can solve this by checking if there's only one argument passed.
var test = function() {
var args = arguments.length == 1 ? arguments[0].join("_") : Array.prototype.join.call(arguments, "_");
return args;
};
console.log(test([1, 2, 3]));
console.log(test(1, 2, 3));
The result is different, because arguments is different.
On the first call (test([1,2,3]), you have one argument which is an array.
On the second call, you have 3 arguments, each one being a number.
Array.prototype.join is meant to be called over arrays. It will stringify each of the items in the array.
In you your first case, your arguments "array" has only one member, which is an array itself. This argument will be stringfied. An array stringfied becomes exactly what is logged in your code.

Random commas appear in array ReactJS

I am trying to create this memory game in ReactJS and I have made an array in which I add 4 random numbers. Now everytime I press play game I need to fill the array with 4 random numbers 0 to 3 but I keep getting random commas that come out of nowhere in the array. I am quite new to React so any help is appreciated.
I have tried different methods of filling up the array but the commas still appear. P.S: keepArray was initialized just before the for loop.
for (let i = 0; i < 4; i++) {
let rand = Math.floor(Math.random() * 4)
keepArray = [...keepArray + rand]
console.log(keepArray)
}
Solution:
Replace:
keepArray = [...keepArray + rand]
with:
keepArray = [...keepArray, rand]
Explanation:
The spread operator (...) is literally "spreading" your array, that's why you need commas. The example bellow may help to visualize it:
// Let's start with a simple array:
var myArray = [1, 2, 3];
// Now, we add another element to it using spread:
var updatedArray = [...myArray, 4];
// Here, ...myArray is translated to [1, 2, 3]
// That means that the above could be read as:
var updatedArray = [1, 2, 3, 4];
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
For an extra explanation about the "+" behavior, see Pavan Bahuguni answer.
The above answer does fix the problem, but the real reason for the behaviour is as follows.
The + operator is overloaded to serve the purposes of both number addition and string concatenation. When + receives an object (including array in your case) for either operand, it first calls the ToPrimitive abstract operation on the value, which then calls the [[DefaultValue]] algorithm with a context hint of number. Which intern calls toString method on the array.
var val = [1,2,3] + 1;
console.log(val); // "1,2,31"
And then you are trying to spread that string in an array like so,
var arr = [...val];
console.log(arr); // ["1", ",", "2", ",", "3", "1"]
this is the actual reason why you are seeing those commas.

How to get value at a specific index of array In JavaScript?

I have an array and simply want to get the element at index 1.
var myValues = new Array();
var valueAtIndex1 = myValues.getValue(1); // (something like this)
How can I get the value at the 1st index of my array in JavaScript?
You can access an element at a specific index using the bracket notation accessor.
var valueAtIndex1 = myValues[1];
On newer browsers/JavaScript engines (see browser compatibility here), you can also use the .at() method on arrays.
var valueAtIndex1 = myValues.at(1);
On positive indexes, both methods work the same (the first one being more common). Array.prototype.at() however allows you to access elements starting from the end of the array by passing a negative number. Passing -1 will give the last element of the array, passing -2 the second last, etc.
See more details at the MDN documentation.
Array indexes in JavaScript start at zero for the first item, so try this:
var firstArrayItem = myValues[0]
Of course, if you actually want the second item in the array at index 1, then it's myValues[1].
See Accessing array elements for more info.
You can just use []:
var valueAtIndex1 = myValues[1];
indexer (array[index]) is the most frequent use. An alternative is at array method:
const cart = ['apple', 'banana', 'pear'];
cart.at(0) // 'apple'
cart.at(2) // 'pear'
If you come from another programming language, maybe it looks more familiar.
shift can be used in places where you want to get the first element (index=0) of an array and chain with other array methods.
example:
const comps = [{}, {}, {}]
const specComp = comps
.map(fn1)
.filter(fn2)
.shift()
Remember shift mutates the array, which is very different from accessing via an indexer.
Update 2022
With ES2022 you can use Array.prototype.at():
const myValues = [1, 2, 3]
myValues.at(1) // 2
at() also supports negative index, which returns an element from the end of the array:
const myValues = [1, 2, 3]
myValues.at(-1) // 3
myValues.at(-2) // 2
Read more:
MDN, JavascriptTutorial, Specifications
You can use [];
var indexValue = Index[1];
As you specifically want to get the element at index 1. You can also achieve this by using Array destructuring from ES6.
const arr = [1, 2, 3, 4];
const [zeroIndex, firstIndex, ...remaining] = arr;
console.log(firstIndex); // 2
Or, As per ES2022. You can also use Array.at()
const arr = [1, 2, 3, 4];
console.log(arr.at(1)); // 2

javascript/jQuery Array concatenation?

I have some simple jQuery code:
var response = Array()
$('.task-list').each(function() {
response.concat(response,$('#' + this.id).sortable('toArray'));
}
);
console.log(response);
The problem I'm having is that I think I'm using concat improperly- the result is an empty array. When I use array push, it works correctly.
You have to set response to the newly formed array, as described in the specification. You currently don't use the return value at all.
The specification says that for .concat, the array is not altered, but the new array is returned:
When the concat method is called with zero or more arguments item1, item2, etc., it returns an array containing the array elements of the object followed by the array elements of each argument in order.
Compare with .push, which says the current array is altered, and that something else is returned instead (the new length):
The arguments are appended to the end of the array, in the order in which they appear. The new length of the array is returned as the result of the call.
So:
response = response.concat($('#' + this.id).sortable('toArray'));
Concat returns the concatenated array, you want this instead
response = response.concat($('#' + this.id).sortable('toArray'));
Simple example
var a = [1,2];
var b = [3,4];
a = a.concat( b ); // result is [1,2,3,4] which is correct
If you do the following
a = a.concat( a , b ); // result is [1, 2, 1, 2, 3, 4] not what you want.

Categories

Resources