Multidimensional array of functions - javascript

How can I make this work:
q = {}
q[0] = new Array()
q[0].push(function()
{
console.log("whatup")
})
q[0]() // currently prints "q[0] is not a function"
Of course, it shouldn't execute until I call it. I tried nesting it inside another function as a return value, but nothing works :(

You have a multidimensional array, but you're only accessing the first dimension at the end (which is another array). Try q[0][0]().

The problem is that the value in q[0] is the new Array() that you assigned to it -- not a function.
These lines:
q[0].push(function()
{
console.log("whatup")
})
will put the function as the first element of the new Array you assigned to q[0] in the second line. So instead of this:
q[0]() // currently prints "q[0] is not a function"
You're really wanting to do this:
q[0][0]()

Your code should work but you're calling the array. To call the function you need to do
q[0][0]()

Related

Function returns [object Set] instead of an actual Set

I have a function
function recursiveDivisionWrap(width, height, colStart, colEnd, rowStart, rowEnd)
in which i have an empty set
let blockedNodes = new Set();
inside this function I have another, recursive function
function recursiveDivision(width, height, colStart, colEnd, rowStart, rowEnd)
On each call of the recursiveDivision function i update a blockedNodes set by adding value:
for (let i = colStart; i < colEnd; i++) {
blockedNodes.add(`c${i}r${wallStart}`);
}
If I console.log blockedNodes set inside recursiveDivision function, I'm getting desired result, for example:
Set(43) {'c0r7', 'c1r7', 'c2r7', 'c3r7', 'c4r7', …}
However when I console.log blockedNodes set inside recursiveDivisionWrap and not in recursiveDivision, I'll get comma separated object:
c0r7,c1r7,c2r7,c3r7,c4r7,c5r7,c6r7,c7r7,c8r7,c9r7,c9r0,c9r1,c9r2,c9r3,c9r4,c9r5,c9r6,c8r0,c8r1,c8r2,c8r3,c8r4,c8r5,c8r6,c3r0,c3r1,c3r2,c3r3,c3r4,c3r5,c3r6,c4r6,c5r6,c6r6,c7r6,c4r1,c5r1,c6r1,c7r1,c4r5,c5r5,c6r5,c7r5
I've also tried with array and the result was the same.
Why doesn't it return Set(43) {'c0r7', 'c1r7', 'c2r7', 'c3r7', 'c4r7', …} if the blockedNodes set is defined outside the recursiveDivision function and inside recursiveDivisionWrap and why does the inner recursiveDivision function returns correct set?
I would appreciate any help in finding answer to that question.
This behaviour has nothing to do with the place where the output is made, but how the output is formatted.
You have these statements:
console.log(blockedNodes);
And:
console.log(`Is this a set? ${blockedNodes}`);
And:
let ecie = Array.from(blockedNodes);
console.log(`Is this an array? ${ecie}`)
They don't do the same thing.
console.log(blockedNodes) leaves the rendering to the console API, which may provide additional information, like the name of the constructor of the object (Set in this case), the number of items this collection has, ...etc. It may even add user-interface controls to expand/collapse the contents of the collection and potential nested data structures.
console.log(`Is this a set? ${blockedNodes}`) will implicitly call blockedNodes.toString() in order to produce the string. Unless toString has been overriden, that will render as [object Set], and so the total output will be "Is this a set? [object Set]".
console.log(`Is this an array? ${ecie}`) will also call the toString method, but this time on ecie, which is an array (as that is what Array.from returned). The toString method on arrays produces a comma separated list of the values, which explains the output you mentioned.

How to add values identified inside a promise to an array in protractor?

I'm trying to add values to an array. Problem is, I can only get the values inside a promise. I tried assigning the values inside the array but when I try to use the array, the only value left is the last one that was assigned.
The values are taken from the page based on the values in a different array. So for example:
var array1 = ['1','2','3'];
var array2 = [];
for (i=1;i<array1.length;i++) {
element(By.xpath(`//div/table/tbody/tr[1]/td[${array1[i]}]`)).getText().then(function(elemText){
array2[i] = elemText;
})
}
I've also tried returning the value:
var array1 = ['1','2','3'];
var array2 = [];
for (i=1;i<array1.length;i++) {
array2[i] = element(By.xpath(`//div/table/tbody/tr[1]/td[${array1[i]}]`)).getText().then(function(elemText){
return elemText;
})
}
But all I got is an array of promises..which, in my case, I can't work with as well because I pass the values on to another method that handles string values and not promises. I know I can make it handle promises, but is there no other way? Or am I just missing something?
any ideas?
I would map each array element to a promise, like such:
var array1 = ['1','2','3'];
var promises = array1.map(function(i) {
return element(By.xpath(`//div/table/tbody/tr[1]/td[${i}]`)).getText();
});
Promise.all(promises).then(function(result) {
// result is your new array here
});
First of all you put your iteration variable i in global objects. Use let key word:
for (let i=1;i<array1.length;i++)
And why do you start from 1? Do you want to skip 1st element of array1? Start with 0 and use let as on example and it'll solve your problem. You run the for loop in stack which executes first. Each iteration of for loop puts a callback in callback queue. When loop is finished you have i=3 in your global object. And all 3 callbacks will work with this exact 3. 'let' works only within curly brackets so it'll close on each callback.

How to think of "forEach" instead of regular for loops?

I'm new to JS and am having trouble getting my head around the "forEach" method.
To help illustrate, let's say that I have 2 arrays.
The first: an array containing 1000 random words from the dictionary.
The second: an array containing 10 "stopwords" (words that I'd like to filter out of the first array).
If I sit down and write a function that takes these two arrays parameters, my intuition would tell me to code it like this:
function cleanSet(theSet, stoppers){
for(var i=0;i<theSet.length;i++){
for(var j=0; j<stoppers.length;j++){
if(theSet[i] === stoppers[j]){
theSet.splice(i,1);
}
}
}
return theSet;
}
However, when I try to use forEach while writing this program, it doesn't work:
function cleanerSet(theSet, stoppers){
theSet.forEach(function(setWord,i){
stoppers.forEach(function(stopper, j){
if(theSet[i] === stopper[j]){
theSet.splice(i,1);
}
});
});
return theSet;
}
Why isn't "cleanerSet" working the way "cleanSet" is?
The problem is that splice mutates your array, so you have to keep in mind that if you delete an item from the array that you are currently iterating, your index is not reset. As far as how to solve it, #Gyandeep provides a good solution. Also, in your first implementation, I think you might've meant:
theSet.splice(i,1);
I think this is what you want to do
function cleanerSet(theSet, stoppers){
return theSet.filter(function(setWord,i){
return stoppers.indexOf(setWord) === -1;
});
}
Runtime:
cleanerSet([1,2,3,4,5], [2,4]) // [1, 3, 5]
Within the callback you pass to the foreach function, the currently iterated value is stored in the first parameter of the function and the current index is stored in the second parameter. So when you check for equality you don't need to reference the index; simply use the parameter (i.e. setWord or stopper).
Additionally, when you call splice, the second parameter should be the number of items you'd like removed, so you need to pass 1, not 'i'.
This modified function should work:
function cleanerSet(theSet, stoppers){
theSet.forEach(function(setWord, i){
stoppers.forEach(function(stopper){
if(setWord === stopper){
theSet.splice(i,1);
}
});
});
return theSet;
}

Jquery function - When called second time, not receiving fresh data, uses old?

I'm having trouble with a function that I'm calling multiple times. Every time I call it, it should receive fresh data (even if its the same as earlier) but somehow, next call to the function will result in what was expected output from the first call to the function.
The code:
$.calc=function(arrayName){
console.log(arrayName);
for(i=0;i<arrayName.length;i++){
if(i==2){
arrayName[i]="";
}
}
}
var arr=new Array();
arr[0]="saab";
arr[1]="saab";
arr[2]="saab";
arr[3]="saab";
arr[4]="volvo";
arr[5]="volvo";
//First run
$.calc(arr);
//Second run
$.calc(arr);
If you run the code (http://jsfiddle.net/76bme/) and open console logger/devtools you can see that I'm printing out the contents of the array that I passed along with the function, BEFORE doing anything with the array.
Next time I call the function, I pass the same array (arr) to the function as in the first call to the function, so I expect that console.log in the beginning to print out the same contents from the array. But now the array holds everything as earlier except at index 2 where I modified it to "" AFTER I printed it out with console.log. If it was the other way around I would get it (having console.log after the for-loop) but now I'm just confused!?
So what am I doing wrong?
That is because arrayName is a reference to your array object. So when you change something in that object, your arr is affected aswell. If you don't want this behaviour, you need to "create a copy" of your array :
$.calc=function(arrayName){
console.log(arrayName)
var myArr = Array.prototype.slice.call(arrayName); //Just here!
for(i=0;i<myArr.length;i++){
if(i==2){
myArr[i]="";
}
}
}
Fiddle : http://jsfiddle.net/76bme/5/
Change
console.log(arrayName);
to
console.log(arrayName.join(";"));
And you will see what you expect. The console [depending on state] does not show a snapshot of the object/array at the current time it was logged, sometimes it stores a reference to it so it will have the current values.

Understanding result returned from splice in CoffeeScript

I am using CoffeeScript along with the JS splice function. My understanding of the JS splice function is that it should return the objects that were spliced out and modify the original array. This seems to work ok with simple arrays but when I start adding objects to the array things break down. Below is a simplified case with comments:
And a link code
#Class that will go in array
class Thing
do: ->
alert "Hi"
a = new Thing
b = new Thing
arr = []
arr.push(a)
arr.push(b)
arr[0].do() # this works
result = arr.splice(0,1)
alert result.do() # this does not work
Does splice do something that makes this not work? If anyone has an idea about the reason this is happening and/or a fix, I would be very appreciative,
Array.splice() returns an array of the element(s) removed; as it has the potential to remove multiple via the second parameter:
Because of this, you should be using alert result[0].do();
Working example: http://jsfiddle.net/Cjtaa/
splice returns an array.
So you need to do:
result = arr.splice(0,1)
alert result[0].do()

Categories

Resources