This question already has answers here:
Does JavaScript pass by reference? [duplicate]
(13 answers)
Closed 3 years ago.
Since arrays are passed to functions by reference, when I set the array to be equal to something else inside a function, and try to log it outside of the function again, why does the value remain the same even though I modified it in the function?
let arr = [1, 2];
console.log(arr); // Logs [1, 2]
add(arr, 3)
console.log(arr); // Logs [1, 2] again
function add(array, el)
{
array = [el];
console.log(array); // Logs [3]
}
Why does the console.log after calling add log out [1, 2] instead of [3] (which is the value of the el parameter)?
You aren't modifying the array.
You're changing the value of the array variable (from a reference to the old array to a reference to a new array).
For comparison, if you were to modify the existing array:
let arr = [1, 2];
console.log(arr);
add(arr, 3)
console.log(arr);
function add(array, el) {
array.length = 0;
array.push(el);
console.log(array);
}
You're confusing the scope of the array.
When you pass in an array to the function and set that variable equal to something else like so;
function add(array, el)
{
array = [el];
}
You're just setting the variable equal to something else and you're not modifying the array. If you want to modify the array you would do something like:
function add(array, el)
{
array[0]=el; // changing the first element to 3
}
Now you will see the array is updated with the first element to 3. This is how it works with updating the array.
If you want the array to be an entirely new array you would do something like:
arr = add(arr, 3);
function add(array, el)
{
array = [el];
return array;
}
Related
let array = [1, 2, 3];
function lastElement(array)
{
if (array === [])
{
return null;
}
else
{
return array.slice(-1);
}
}
you are doing it in the wrong way, you cannot check if an array is empty like you did.
function lastElement(array) {
if(array.length == 0) return null
return array[array.length - 1]
}
array.length returns the count of elements inside an array.
You also need not to add an else statement because if we are returning from a functions, the code below that line does not get executed.
Hi I seen you are facing the issue of checking array and slice the data also.
Simply if you want to check the array is empty or not you will using something like this in the js
To get the last element of an array you can use
let array = [1, 2, 3];
console.log(array.length-1);
To Check array is empty and also get the last element of an array
let array = [1, 2, 3];
function lastElement(array) {
if(array.length == 0) return null
return array[array.length - 1]
}
console.log(lastElement(array))
To know more about slice which you have used in the above problem click here
I'm trying to remove an item from an array using the indexOf() with splice() technique suggested. This is what's happening
let someArray: string[] = [first, second, third, fourth, fifth, sixth];
let newArray: string[] = someArray.splice(3, 1);
console.log(newArray);
//deisred result = [first, second, third, fifth, sixth]
//result I'm getting = [fourth]
That's not what virtually every article I've come across says should happen. Can someone shed light on this?
UPDATE
I discovered this problem in my code when I was only ghetting 1 result where I was expecting more and tracked it back to this point.
Because when you splice an array you are mutating it, which means you are changing the original array. You're storing the result (the element you're splicing from the array) within the "newArray" variable that you have created here. So this:
var arr = [1, 2, 3, 4];
var mine = arr.splice(1, 1);
console.log(mine);
console.log(arr);
would return the original ray minus index one if we print arr to the console, and will return [2] if we print mine to the console. To get the output you're expecting, you would have to perform a different operation such as iterating through the array and utilizing splice differently. Here is an example:
var arr = [1, 2, 3, 4];
var mine = [];
for(var i = 0; i < arr.length; i++) {
if(i !== 3) {
mine.push(arr[i]);
}
}
Now I am not mutating the original array, and I am simply pushing the elements to a new array.
But if you want to simply mutate the original array and not store the new array in some sort of variable you can simply splice the original array:
var arr = [1, 2, 3, 4];
arr.splice(3, 1);
console.log(arr);
However, if you are passing it to a function, i'd probably not mutate an array outside of the function, and i'd simply return a value and store that value in a new variable:
var arr = [1, 2, 3, 4];
function deleteIndex(ar, i) {
var a = [];
ar.forEach(function(elt, index) {
if(index === i) {
}
else {
a.push(elt);
}
});
return a;
}
var newArr = deleteIndex(arr, 3);
console.log(newArr);
This way you can delete any index, or pass a function and criteria that you would want to use to determine if an index should be deleted, without changing to top-level structure of your original array by utilizing functional programming. There are also some function in the underscore module that can help you if that's the case.
Let say I have an array:-
var arr = [0,1,2,3,4]
I need to pass only "1" and "4" to function below
function func1(onlyArray){
//Do Stuff...
}
I have tried both but both also dont work
func1(arr[1,4])
func1(arr[[1],[4]])
Can anyone show me the right way or give me some keyword?
You can use this:
func([arr[1], arr[4]])
We are taking the elements at index 1 and 4 of the array arr and creating a new array with those elements. Then we pass that newly created array to func.
If you need a single array instead of 2, use this:
var arr = [0,1,2,3,4];
function func1(onlyArray){
//Do Stuff...
console.log(onlyArray); // [1, 4]
}
func1(arr.filter((item,index) => index === 1 || index === 4));
So using your array:
var arr = [0,1,2,3,4];
and your function:
function myFunction(newArr){
//Do stuff
console.log(newArr);
};
You can wrap the array indexes you want to use inside of their own array when you call the function, like the following:
myFunction([arr[1], arr[4]]); //Output is [1, 4]
Why does the first console.log() print undefined values but second one has transformed values? I know it has to do something with function scope but not getting it
var array = [1,2,3,4,5,7];
function incrementByOne(arr) {
arr = arr.map(function(value, index, array){
arr[index] = arr[index] +1;
});
console.log(arr);
}
incrementByOne(array);
console.log(array);
// [undefined, undefined, undefined, undefined, undefined, undefined]
// [2, 3, 4, 5, 6, 8]
also i notice that the first console.log() knows how many times to iterate but what happens to the value...
js bin link
you need to return the incremented value from the function inside map. use return arr[index] +1
Also you need to return the new array formed using map and stored in arr now.
var array = [1,2,3,4,5,7];
function incrementByOne(arr) { //contains array reference
arr = arr.map(function(value, index, array){
return value +1;
});
//now arr contains a new array and doesn't refer to passed array anymore.
console.log(arr);
return arr;
}
array = incrementByOne(array);
console.log(array);
// [undefined, undefined, undefined, undefined, undefined, undefined]
// [2, 3, 4, 5, 6, 8]
if you don't want to return, you can use forEach(), as in that case arr will refer to passed array throughout. The difference is because map returns a new array.
var array = [1,2,3,4,5,7];
function incrementByOne(arr) { //contains array reference
arr.forEach(function(value, index){
arr[index] = value +1;
});
//arr still refers to the passed array.
console.log(arr);
}
incrementByOne(array);
console.log(array);
// [undefined, undefined, undefined, undefined, undefined, undefined]
// [2, 3, 4, 5, 6, 8]
Well, all the above answers are correct but they miss the most important point here. There is a concept in JavaScript called call by sharing.
Consider this code:
var num= 3;
var json = {myValue : '10'};
var json2 = {myValue : '100'};
function callBySharing(a,b,c){
a = a + 37;
b = {myValue : 'new value'};
c.myValue = 'new Value';
}
callBySharing(num,json,json2);
console.log(num);//3 *UNCHANGED*
console.log(json.myValue);//10 *UNCHANGED*
console.log(json2.myValue);//'new Value' *CHANGED*
So what you are doing is same as what is happening in json.myvalue; You are trying to update the whole object and replace it with the new value. So a very simple change in the code with do this for you:
var array = [1,2,3,4,5,7];
function incrementByOne(arr) {
arr.map(function(value, index, array){
arr[index] = arr[index] +1;
});
console.log(arr);
}
incrementByOne(array);
console.log(array);
I just replaced the arr= arr.map().... part to just arr.map().....
What this does is, it changes the function to json2.myValue example case.
So what is the difference between the 2: JS lets you update items within the object but not the whole object.By making the above said change in code, you are updating individual values of arr and not replacing the whole object with new values. I learnt this concept from SO only back when I was confused with it. So I am linking the post(Is JavaScript a pass-by-reference or pass-by-value language?)
Hope this helps!
var array = [1,2,3,4,5,7];
function incrementByOne(arr) {
arr = arr.map(v => v + 1);
console.log(arr);
}
incrementByOne(array);
console.log(array);
// [undefined, undefined, undefined, undefined, undefined, undefined]
// [2, 3, 4, 5, 6, 8]
A couple of things going on here:
The callback you pass into the .map function should return a value with the return keyword. If you don't return a value from the callback, the default return value is undefined. That's why the 'arr' array you define in incrementByOne only has undefined values inside of it when you log it with your first console.log. I think what you're really trying to do is simply return value + 1 inside of the callback.
You're making a classic passed-by-value passed-by-reference error here; it's a mistake everyone makes when they're first learning JS. I'd recommend checking out posts like this one. In short, inside of your .map callback you are mutating the array that you passed into incrementByOne, which is the same array you log out with the second console.log; that's why the values appear to have been incremented correctly.
For the life of me, I just can't figure out what I'm doing wrong here.
I'm trying to use both the reduce and concat array methods to take all of the values of a 2d array and combine them into a single value (basically condense them into a single array and then sum them up).
The problem that I keep running into is that when I try to make a for/loop to concat each array element, the argument that I'm passing into the function is not being recognized as an array, thus my call to .concat() is failing. I've placed a console.log() at the beginning of the function to see if the element is being recognized as the first array element in the 2d array, and it's coming up as "1"(?).
I tried another test outside of the function, and it logs as the actual array element. What am I doing wrong here? code below:
var arrays = [[1, 2, 3], [4, 5], [6]];
var myArray = arrays[0]; // Test
console.log(myArray); // Test
var flatArray = arrays.reduce(function(arrays)
{
console.log(arrays[0]); // Test
for (var i = 0; i < arrays.length - 1; i++)
{
arrays[0].concat(arrays[i+1]);
}
return arrays;
});
console.log(flatArray);
This is the output that I keep getting:
Array [ 1, 2, 3 ]
1
TypeError: arrays[0].concat is not a function
It's almost seems like array is being converted to a number-type when inside the function...?
You have an error in your code here:
var flatArray = arrays.reduce(function(param) {})
that param will be an element of your arrays vector.
Check this https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
You are using .reduce() incorrectly and you don't even need to use it to flatten an array. You can just do this:
var flatArray = [].concat.apply([],arrays);
Working demo: http://jsfiddle.net/jfriend00/wfjyfp42/
To understand .reduce(), the callback you pass it gets four arguments (see MDN reference). The first two arguments are important in using .reduce() correctly:
callback(previousValue, currentValue, index, array)
The previousValue is the accumulated value so far in the reduction. The currentValue is the next element of the array that is being iterated. The last two arguments do not need to be used if not needed.
Your code is only using the previousValue so it is never looking at the next item in the array as passed in by .reduce().
You could make a solution work using .reduce() like this:
var flatArray = arrays.reduce(function(previousValue, currentValue) {
return previousValue.concat(currentValue);
}, []);
Working demo: http://jsfiddle.net/jfriend00/2doohfc5/
Reduce performs an operation on two elements.
var sum = [[1, 2, 3], [4, 5], [6]].reduce(function(a, b) {
return a.concat(b);
}).reduce(function(a, b) {
return a + b;
});