This question already has answers here:
"Variable" variables in JavaScript
(9 answers)
Closed 2 years ago.
I wrote a Javascript function and a loop whose role is to call my function, each time with a different parameter. My idea was that the iterator will help me use a different variable each time but obviously this doesn't work. I figured out that my problem is that when the loop calls the function, the parameter is a string rather than an object name. Any way to save that or the idea was flawed from the beginning?
var a0 = [1,2,3];
var a1 = [4,5,6];
var a2 = [7,8,9];
function myFunction (parameter) {instructions;}
for (i=0; i<3; i++)
myFunction("a"+i);
You could wrap the arrays in an array and iterate this array.
function myFunction(reference) {
console.log(...reference);
}
let a0 = [1, 2, 3],
a1 = [4, 5, 6],
a2 = [7, 8, 9];
for (const array of [a0, a1, a2]) myFunction(array);
Related
This question already has answers here:
javascript for loop changes original list variable
(3 answers)
Closed 2 years ago.
From what I understand, when an array object is assigned to a new variable, that array object can be "referenced" between both variables, but the values themselve are mutable by either assigned variable.
At least that appears to be the case.
let variable1 = [6, 3, 2, 6, 7, 2, 9, 1, 5];
let variable2 = variable1;
for (i = 0; i < 10; i++) {
variable2.unshift(i);
}
console.log(variable1);
> [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 6, 3, 2, 6, 7, 2, 9, 1, 5]
Am I only able to timestamp the state of my data at a given point in the run time by creating a new array and pushing in the contents of the previous array, or is there another practice used? Thanks.
Array.from()
const array2 = Array.from(array1)
console.log(array2)
If you don't want this behaviour, you have to make sure to use methods that generate a new array on every mutation of the original array.
To copy an array you can use Array.from(array) or ES6 [...array].
With that knowledge: For array.unshift(e) you can use ES6 array = [...array, e];
let variable1 = [6, 3, 2, 6, 7, 2, 9, 1, 5];
let variable2 = variable1;
for (i = 0; i < 10; i++) {
variable2 = [...variable2, i];
}
console.log('var2', variable1);
console.log('var1', variable2);
Javascript generally is always pass by value, but in the case when the variable refers to an object (including arrays) the "value" is a reference to that object.
When you change the value of a variable, it doesn't change the underlying object or primitive - instead it just points the variable to the new value.
However changing properties on an object (including arrays) will change the underlying object itself.
tl;dr
There is no way to capture the state at a given timepoint without making a complete copy of it.
How to create the copy
Depending on how your data is structured there are multiple ways you could go about to create a clone of it.
If it is just an array of primitives, e.g. an array of numbers / strings, a shallow copy of the array would suffice:
const arr = [1,2,3,"foo"];
// using array spread
const clone1 = [...arr];
// Array.from()
const clone2 = Array.from(arr);
// mapping the array
const clone3 = arr.map(e => e);
// push with spread
const clone4 = [];
clone4.push(...arr);
// good old for loop
const clone5 = [];
for(let i = 0; i < arr.length; i++)
clone5.push(arr[i]);
If you have a deep data structure with nested objects / arrays, you need to do the shallow copying recursively to achieve a deep copy.
However there are already lots of good libraries that can handle these for you, for example lodash:
const value = [{a: 1}, {b: 2}, {c: ["a", "b"]}];
// using lodash _.cloneDeep to get a deep copy
const clone = _.cloneDeep(value);
This question already has answers here:
Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array
(97 answers)
Closed 6 years ago.
There is a javascript array
var arr = [0, 1, 2, 2, 3, 3, 5];
I want to choose elements that repeats twice. In this case its 2 and 3. and i want attach them into a variable.
var a = 2, b = 3;
As far as i know there is no built-in function to do that job. How can i do that. Thanks.
You can use filter to get the values that occur twice.
var arr = [0, 1, 2, 2, 3, 3, 5];
var dups = arr.filter ( (v,i,a) => a.indexOf(v) < i );
console.log(dups);
In comments you stated you would only have doubles, but no values that occur more than twice. Note that the above would return a value more than once, if the latter would be the case.
This returns the values in an array, which is how you should work. To put them in separate values can be done as follows:
var [a, b, ...others] = dups;
...but you would have to know how many variables to reserve for that, and it does not make your further program any easier. JavaScript has many nice functions (methods) for arrays, so you should in fact leave them in an array.
There is no built in function to do that indeed.
You will have to loop thought the array and keeping track of the number of occurrences of the elements, while building a response array.
You could filter a sorted array.
var arr = [0, 1, 2, 2, 3, 3, 5],
repeats = arr.filter(function (a, i, aa) {
return aa[i - 1] === a;
});
console.log(repeats);
Most simple way to do this is the following:
var dups = [];
var arr = [0, 1, 2, 2, 3, 3, 5];
arr.forEach(function (v, i, a){
delete arr[i];
if (arr.indexOf(v) !== -1){
dups.push(v);
}
});
console.log(dups);
It's destructive however.
This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
I have tried this:
// You can pass an array on the addArr method, and each element from the
// passed array is pushed to the array on which addArr was called.
Array.prototype.addArr = function( arr ){
console.log( this );
// As `this` is the array, we use this.push to insert arr's elements
arr.forEach(function(elm){
this.push( elm );
});
// And then finally return this.
return this;
};
The code has been explained using comments, but let me put in straight. I am trying to create a new method on the Array object called addArr, which can pass an array [1, 2, 3] to the method and each of the element is added to the array on which the method was called.
For e.g
var myArr = [1, 2, 3];
myArr.addArr( [4, 5, 6] );
// The output is supposed to be [1, 2, 3, 4, 5, 6]
I am getting Uncaught TypeError: this.push is not a function, I have tried debugging, this always returns the parent array still it says that push is not a function.
How can I solve it? I could use libraries like Lodash for these, but I don't prefer to for such a small application.
Thanks!
Store this into a variable outside of the function.
Array.prototype.addArr = function( arr ){
var that = this;
arr.forEach(function(elm){
that.push( elm );
});
return this;
};
var myArr = [1,2,3];
myArr.addArr([4,5]);
Alternative, as #nnnnnn pointed out, you could pass this as an argument to the .forEach function.
Array.prototype.addArr = function( arr ){
arr.forEach(function(elm){
this.push( elm );
},this);
return this;
};
var myArr = [1,2,3];
myArr.addArr([4,5]);
This question already has answers here:
Functional approach to basic array construction
(5 answers)
Closed 8 years ago.
I'm trying to create a function that returns an array with n elements, that are all the same function (this array will later be used to call those functions in parallel using async).
I can easily loop over an array and add the function to each element, but was wondering if I can do it in one line, using map:
//the function to point to
var double = function(x) {
return x*2;
};
//this function will create the array - just a filler for a one-liner
var createConsumersArray = function(numOfConsumers) {
var consumers = (new Array(2)).map(function(x){return double;});
return consumers;
};
var t = createConsumersArray(2);
console.log(t); //prints [,]
console.log(t[1](2)); //TypeError: Property '1' of object , is not a function
If I pre-fill the array with constants, the map works, i.e.:
var x = [1,2,3];
console.log(x.map(function(x){return double;})); //prints [ [Function], [Function], [Function] ]
console.log(x[1](2)); //prints 4
How can I accomplish filling an array with an identical function in the shortest way?
You have to change a little.
var createConsumersArray = function(numOfConsumers) {
var consumers = Array.apply(null, Array(numOfConsumers)).map(function(){return double;});
return consumers;
};
This is more functional programming. If you'd like to program in this style, I'd recommend you look at underscore.js. Here's an example of a range function:
_.range(10);
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
For your use case you would do:
_.map(_.range(4), function(num){ return double; });
Here's the corresponding jsfiddle example:
This question already has answers here:
JavaScript by reference vs. by value [duplicate]
(4 answers)
Closed 8 years ago.
I was reading on this blog about how if an object or array were changed inside of a function, the value in memory that was pointed to would be changed as well, the same as if it were changed outside the function.
var a = [1,2,3],
b = a;
b[0] = 5;
console.log(a); // [5, 2, 3]
would result in the same as
var a = [1,2,3],
b = a;
var arrayFunction = function(arr){
arr[0] = 10;
};
var arr = arrayFunction(b);
console.log(a, b, arr) // [10, 2, 3], [10, 2, 3], [10, 2, 3];
Yet what I can't understand is why reassigning multiple array values within the function does not change the values outside of it:
var a = [1,2,3],
b = a;
var arrayFunction = function(arr){
arr = ["a", "b", "c"];
return arr;
};
var result = arrayFunction(b);
console.log(result) //["a", "b", "c"]
console.log(a, b); //[1, 2, 3], [1, 2, 3]
Why does this not change the pointed to value in memory like in the first example?
Probably a better job of writing out the examples on the JSBIN
This is because objects in javascript aren't really passed by reference. I've seen it referred to as "passed by copied reference", or "passed by handle" - both of which do a better job of describing what's really happening.
In this example:
var b = [1, 2, 3];
var arrayFunction = function(arr) {
arr = ["a", "b", "c"];
};
arrayFunction(b);
The object reference itself is passed by value. You're not actually changing the value of the b variable. However, your function argument (arr) and the b variable are initially pointing to the same object - so if you change one, you can reference the object through either and see the change.
When you reassign arr to point to a different object though, the b variable is still pointing to the old object, and does not change.
Remember that, within the function, arr is not the actual array; arr is a reference that points to the array.
So when you say arr[0], you're retrieving the array, and then getting or updating an item in it.
But when you say arr = ["a","b","c"], you are creating a new object (on the right side) and then turning arr into a reference that points to the new object.
In Javascript a variable merely points to an array; so if you copy the variable you get two variables pointing to the same array:
var a = [1,2,3];
var b = a;
Changing an element of the array with a[0] = 99 will be observable with both variables because there is just one array and both a and b are pointing to it.
When you write instead
a = [5, 6, 7];
you are setting a to point to another different array.
Javascript never makes a copy of an array unless you ask it explicitly (e.g. with b = a.slice()).
Actually the very same happens with any value (objects for example). With numbers and string the same logic is also valid, but it's hard to notice the difference between a copy and sharing the same object because numbers and strings cannot be changed (the're "immutable").
In other languages like C and C++ instead variables contain the value, not a pointer; so when making an assignment for example objects are copied from one variable to the other and if you want a pointer you've to ask explicitly for it.