Execute function with array as parameters - javascript

I have an array with random count of elements, for example:
var array = [1, 2];
And I want to execute some function with the next parameters:
functionName(SOME_CONST, array[0], array[1])
What is the best way to do this, considering that array could have a different number of parameters?

Have a look at https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply for details on how to use the Function.prototype.apply method.
So long as you want to use all of the items in your array as arguments in the function that you are calling, you can use:
function some_method(a, b, c) {}
var array = [1,2];
some_method.apply(this, ['SOME_CONST'].concat(array));
which will result in calling some_method with a being the 'SOME_CONST' and b and c being the first two elements in the array. If you had more elements in the array, they would come next in the arguments list in the some_method function.

You can just call the function and pass in the array itself instead of it's elements like this
function functionName(SOME_CONST, myArray){
//myArray contains the same elemnts here too
}
then you can call the function like this
var myArray = [1,2];
functionName(CONST_VAL,myArray);

The simplest solution would be to pass the whole array to the function and have the function iterate over it. This would allow for a variable length array.
functionName(SOME_CONST, array) {
for (var ii = 0, len = array.length; ii < len; ii++) {
// do something.
}
}

Use .apply, and array join, i mean create new array, let the SOME_CONST be the first element and join the other array which you already have.
You can do like this,
var array = [1, 2];
functionName.apply(thisObj || window, [SOME_CONST].join(array));
function functionName(a, b, c){
//a is SOME_CONST, b is 1 and c is 2
}
thisObj is the scope/context of the function which you are calling. If you dont have a thisObj just pass window object

Related

Javascript array concatenation

I have three variables a, b and c. I have to insert these into an array called arr. On calling function click, these variables should get pushed into arr array. eg. if i call click with arg 1,2 & 3 then array should be [1,2,3], now when I will pass the args 6,7 then the array should be [1,2,3,6,7].
In the code below, I tried to use concat method to get the desired result but i was unsuccessful.Is there any way around this?
function click(a,b,c){
var A=a;
var B=b;
var C=c;
var arr=[]
var newArr=[A,B,C]
arr.concat(newArr);
console.log(arr);
}
click(10,11,12);
click(12,13,14);
Declare a global array outside of the function and then after push values into it.
var arr = [];
function click(a,b,c){
arr.push(a, b, c)
}
click(10,11,12);
click(12,13,14);
console.log(arr);
The problem with your code is that, you are concatenating to the array but not considering the return value.
arr = arr.concat(newArr);
Then declare the array global to hold the values for every click.
function click(arr, a, b, c){
arr.push(a, b, c);
console.log(arr);
}
var arr = [];
click(arr, 10, 11, 12);
click(arr, 12, 13, 14);
If you don't want your arr outside your function, another approach is storing your arr inside click scope then call it anywhere (it doesn't pollute your global scope):
let click = (function (arr) {
return function (a,b,c) {
var A=a;
var B=b;
var C=c;
var newArr=[A,B,C]
arr = arr.concat(newArr);
console.log(arr);
}
})([])
click(10,11,12);
click(12,13,14);
First of all. You should either define arr outside your function or pass arr into function as a parameter.
Second one. Function concat returns concatenated arrays and left original arrays unchanged. So you need something like arr=arr.concat(newArr)
Destructuring assignment can be used to functionally concatenate
variables with arrays.
See below for a practical example.
// Input.
const input = [1, 2, 3]
// Click.
const click = (array, ...arguments) => [...array, ...arguments]
// Output.
const output = click(input, 4, 5, 6)
// Proof.
console.log(output)
Your Problem here is that the concat function returns a new array instance with the elements:
Check Here
function click(a,b,c){
var A=a;
var B=b;
var C=c;
var arr=[]
var newArr=[A,B,C]
arr = arr.concat(newArr);
// concat does not change the ref itself
console.log(arr);
}
click(10,11,12);
click(12,13,14);

javascript findIndex callback arguments

I'm new to javascript.
I'm trying to find the index of a specific element in an array. I read about that I can use findIndex to loop through an array. But it seems that findIndex only accept three arguments: element, index and array. What if I want change the object that is used to be compared.
For example, I want for find the index of string 'b' in array ['a','b','c'],
var position = ['a','b','c'].findIndex(function(element, index, array){return element==='b'})
but how do I pass 'b' as parameters that I can change to callback function
Thanks
What about indexOf function? You just have to pass one argument, as searched element.
let arr = ['a','b','c'];
console.log(arr.indexOf('b'));
You can define the wanted character from the outside context inside the callback function:
var wantedChar = 'c';
var position = ['a','b','c'].findIndex(function(element, index, array){return element===wantedChar})
console.log(position);
By doing so, you can wrap all that up in a function:
var findPos = function(arr, char){
return arr.findIndex(function(element, index, array){return element===char});
}
console.log(findPos(['a','b','c'], 'c'));
Note: as already suggested, it makes more sense to use indexOf when just comparing strings. The findIndexfunction in combination with a custom callback is there for more sophisticated search, e.g. when dealing with complex structured objects.
function getPosition(){
var position = ["a","b","c"];
var a = position.indexOf("b");
document.getElementById("demo").innerHTML = a;
}
<button onclick="getPosition()">button</button>
<p id="demo"></p>

How does the [].push.apply work?

can someone please explain me how does this line of code work.
[].push.apply(perms, permutation(arr.slice(0), start + 1, last));
This function generates an array of all permutations of an input array;
var permutation = function(arr, start, last){
var length = arr.length;
if(!start){
start = 0;
}
if(!last){
last = length - 1;
}
if( last === start){
return [arr];
}
var temp;
var perms = [];
for(var i = start; i < length; i++){
swapIndex(arr, i, start);
console.log(arr);
[].push.apply(perms, permutation(arr.slice(0), start + 1, last));
swapIndex(arr, i, start);
}
return perms;
};
[].push creates a new array, then fetches push which is the same as Array.prototype.push but with creating an unused object each time that needs to be garbage collected.
If you call Array.prototype.push(5) it wont work since this wouldn't be set to an array or something that extends an array. Thus you need to use either Function.call, Function.apply or Function.bind to set this if you want to use an arbitrary function to work as a method.
If you have
Array.prototype.push.apply(thisObject, arrArguments) is the same as
thisObject.push(arrArguments[0], arrArguments[1], ..., arrArguments[n]) if thisObject has push in its prototype chain. Since perms is an array and has push in it's own prototype chain it could be replaced with:
perms.push.apply(perms, permutation(arr.slice(0), start + 1, last));
The use of apply is because push gets all the contents of the permutations array as arguments. thus if permutations(....) returned [1,2,3] it would be synonymous with perms.push(1, 2, 3). You could write it without apply by calling push for each element:
for (var e of permutation(arr.slice(0), start + 1, last)) {
perms.push(e);
}
And in ES6 you can simply use the spread syntax which is the same as apply but simpler to comprehend:
perms.push(...permutation(arr.slice(0), start + 1, last))
Expanded it is the same as:
Array.prototype.push.apply(arrryToPushTo, ArrayOfItemsToPush)
apply() is from Function.prototype.apply() and Array.prototype.push is a function.
Using an empty array instead of writing "Array.prototype" exposes the push() method that apply() can be called on and is done simply because "[]" is less characters to write than "Array.prototype".

How to initialize 4d array in javascript?

Here is my code:
var arr = [[[[[]]]]];
var c = 20;
for (i=0;i<5;i++)
arr[i][0][0][0] = c;
alert(arr[2][0][0][0]);
It doesn't work, but how can I do this?
Most people here are using for loops, which I think are mostly obsolete in the age of anonymous functions in JavaScript. You people should know better :P
Anyway, you can solve this quite nicely in a one-liner. Here are a few scripts that can initialize your array...
If you already have a 4-dimensional array, you can initialize it elegantly like this:
arr.forEach(function(e) { e[0][0][0] = c })
Or, if you're more into map:
arr.map(function(e) { e[0][0][0] = c })
These are assuming you already have c defined, which you do in your code sample (20).
From now on, though, please Google your questions before asking them on stackoverflow. You will receive an answer that has already been accepted :)
It doesn't work because you haven't specified any elements beyond the first one, so the length of array is one and accessing further keys is incorrect.
I think, the most convenient way would be to push a new 3d array with c inside on every iteration (actually I have no idea what you're trying to achieve with this xD):
var arr = [];
var c = 20;
for (i=0;i<5;i++)
arr.push([[[c]]])
alert(arr[2][0][0][0]);
(in your example it's actually 5d, but as you've asked for 4d, writing 4d there)
It is unclear what you want, but I imagine a 4 dimension array is an array that has a set of arrays nested 3 deep, each of which has an array nested 2 deep, each of which has a single array that contains values.
In a one dimension array, you access the value at index 2 by:
arr[2];
In a two dimension array, you'd access the value at (2,3) by:
arr[2][3]
and so on until you get to the value at (2,3,1,2) in a four dimension array by:
arr[2][3][1][2]
and if that was the only value in the array, it would look like:
[,,[,,,[,[,,'value at 2312']]]];
If there was also a value at (1,1,0,2) the array would now look like:
[,[,[[,,'value at 1102']]],[,,,[,[,,'value at 2312']]]];
There can only be values in the last nested array, the value at indexes in every other array must be another array (for the lower dimensions), so to insert at value at, say (2,1,3,1) and assign it a value of 6, you need to loop over the array and inspect each index. If it's not already an array, insert an array and keep going, e.g.:
// Insert value in arrary at coord
// coord is a comma separated list of coordinates.
function insertValue( array, coord, value) {
var coords = coord.split(',');
var arr = array;
for (var c, i=0, iLen=coords.length-1; i < iLen; i++) {
c = coords[i];
if (!Array.isArray(arr[c])) arr[c] = [];
arr = arr[c];
}
arr[coords[i]] = value;
return array;
}
document.write('result: ' + JSON.stringify(insertValue([],'1,2,1,3','at 1213')));
I don't understand what you are trying to do in the OP: are you trying to create a value of 20 at coordinates (0,0,0,0), (1,0,0,0), (2,0,0,0), etc.? If that is the case, you also need a fill function that will iterate for the required number of times and pass suitable arguments to insertValue.
If that's what you want, then given the above you should be able to write such a function. On the first iteration it would pass:
insertValue(array, '0,0,0,0', 20)
and on the second:
insertValue(array, '1,0,0,0', 20)
and so on. You may wish to modify the function so that instead of the coords being a CSV string, you pass an array like [0,0,0,0] (which is what split turns the CSV string into), but that's up to you.
Note that you must pass all 4 dimensions, otherwise you will replace one of the dimension arrays with a value and effectively delete all other points in that dimension sector.
PS
ES5 introduced forEach, which helps encapsulate loops but doesn't necessarily mean less code, or faster execution, than an equivalent for loop:
// Insert value in arr at coord
// coord is a comma separated list of coordinates.
function insertValue( array, coord, value) {
var arr = array;
var coords = coord.split(',');
var last = coords.pop();
coords.forEach(function(c) {
if (!Array.isArray(arr[c])) arr[c] = [];
arr = arr[c];
})
arr[last] = value;
return array;
}
Create array with 5 nested arrays:
var arr = [[[[[]]]], [[[[]]]], [[[[]]]], [[[[]]]], [[[[]]]], [[[[]]]]];
var c = 20;
for (i=0;i<5;i++)
arr[i][0][0][0] = c;
alert(arr[2][0][0][0]);
EDIT: if you dig into functional programming and recursion, you can initialize your multidimensional array with just a few lines of code. Let's say you want 4-dimensional array with length 10 of each dimension:
function createNDimensionalArray(n, length) {
return n === 1
? new Array(length)
: Array.apply(null, Array(length)).map(createNDimensionalArray.bind(null, n - 1, length));
}
var arr = createNDimensionalArray(4, 10);
console.log(arr); // creates 4-dimensional array 10x10x10x10
Notice that initialization like this could be very slow if you create very big arrays (e.g. createNDimensionalArray(5, 10000).
If you prefer to set length of each dimension, you can modify previous the solution like this:
function createNDimensionalArray(dims) {
return dims.length === 1
? new Array(dims[0])
: Array.apply(null, Array(dims[0])).map(createNDimensionalArray.bind(null, dims.slice(1)));
}
var arr = createNDimensionalArray([2, 3, 4, 5]);
console.log(arr); // creates 4-dimensional array 2x3x4x5

JS Multidimensional Array with No Fixed Size

In my program I have:
an array currentIndex that will look something like [1, 2, 2]
a multidimensional array directions that looks like [1, [2, 0, [2, 3, -]] 1]
How can I loop through the first one in such a way that I can access directions[1][2][2] (turn the first array in the indexes of the second) ?
To access directly one value you could use vector[1][2], but remember that the array index starts with 0.
But, if you want to walk through the vector you need a recursive function:
function printRecursiveArray(value, c){
for(c=0; c<value.length; c++){
if (typeof value[c] !=='object'){
console.log(value[c]);
}else{
printRecursiveArray(value[c],0);
}
}
}
var vector = [1,[1,2,3],2,3];
printRecursiveArray(vector,0);
console.log('vector[1][2]:' + vector[1][2]);// To access directly
So, your array could have any dimension, but you still print the elements.
From what I understand you want to iterate through the first array where each value in the first array is the index you want to access in the multidimensional array. The following recursive function should work:
//index: Array of indexes
//arr: The mutlidimensional array
function accessMutliArr (index, arr) {
if (index.length === 1)
return arr [ index ];
else {
var currentIndex = index.splice(0, 1);
return accessMutliArr (index , arr [ currentIndex ]);
}
}
If you want to loop over a multidimensional Array then the process can look like:
for(var i in directions){
for(var n in direction[i]){
for(var q in directions[i][n]){
var innerIncrement = q, innerValue = directions[i][n][q];
}
}
}
Take into account that a for in loop will automatically make your indexes Strings. The following is a fail proof way to do the same thing, with some other help:
for(var i=0,l=directions.length; i<l; i++){
var d = directions[i];
for(var n=0,c=d.length; n<c; n++){
var d1 = d[n];
for(var q=0,p=d1.length; q<p; q++){
var innerIncrement = q, innerValue = d1[q];
}
}
}
When you do a loop like either of the above, imagine that each inner loop runs full circle, before the outer loop increases its increment, then it runs full circle again. You really have to know what your goal is to implement these loops.

Categories

Resources