I'm trying to pass positions of a list of arrays in a function, but I'm definitely missing something.
This is my script :
// function to display the results
function display(array){
var source = SpreadsheetApp.openById("x");
var sheet = source.getSheetByName('x')
var value = sheet.getRange("G4:I4").setValue(array[x][y]) //sets the range to the value
}
// function that creates or searches for the array
function recherche() {
var source = SpreadsheetApp.openById("x");
var sheet = source.getSheetByName('x')
var arrays = [
[1,2,3,4,5],
[6,7,8,9,10]
]
display(arrays[0][0]) // first time it is executed it should display arrays[0][0] or 1
return arrays
}
// function to display the next value
function next(){
var source = SpreadsheetApp.openById("x");
var sheet = source.getSheetByName('x')
display(recherche()[x+1][0]) // should display arrays[1][0] or 6
}
Am I doing something stupid or did I just miss something?
Thx
There are so many ways to do this:
First:
function myTest() {
let i = 0;
let arrays = rechershe(); // will display arrays[0][0]
i++;
next(arrays,i);
}
function next(arrays,i) {
display(arrays[i][0]);
}
Or:
function myTest() {
let i = 0;
let arrays = rechershe(); // will display arrays[0][0]
i++;
next(arrays[i][0]);
}
function next(value) {
display(value);
}
Or:
function myTest() {
let i = 0;
let arrays = recherche(); // will display arrays[0][0]
i++;
function next() {
display(arrays[i][0]);
}
next(); // will display arrays[1][0]
}
And still another:
function myTest() {
let i = 0;
let arrays = recherche();
i++;
next = () => display(arrays[0][i]);
next();
i++;
next();
}
8:15:58 AM Notice Execution started
8:16:00 AM Info 1
8:16:00 AM Info 2
8:16:00 AM Info 3
8:15:59 AM Notice Execution completed
Related
I am trying to create an array from an asynchronous get request using a function that uses a for loop in order to pass a parameter in the get request.
var loadRarity = function () {
var rarities = [];
for (var i =0; i < deck.length; i++) {
Card.get({cardName: deck[i].card_name}, function(data) {
rarities.push(data.data[0].rarity);
console.log(rarities); //20 instances where the array is being populated
});
console.log(rarities);// result :20x [] empty array
}
return rarities;
};
var raritiesArray = loadRarity();
console.log(raritiesArray); //empty array
I can't figure out how to use the callback to make this work.
An option is to increment a counter to check if you are on the last callback an then do any needed operation in that last callback
var loadRarity = function () {
var rarities = [];
var counter = 0; // initialize counter
for (var i =0; i < deck.length; i++) {
Card.get({cardName: deck[i].card_name}, function(data) {
counter += 1; //increment counter
rarities.push(data.data[0].rarity);
console.log(rarities); //20 instances where the array is being populated
if(counter == deck.length){ //if true you are in the last callback
console.log(raritiesArray); // array with all the elements
}
});
}
return rarities;
};
var raritiesArray = loadRarity();
Waiting for all this async stuff to happen, your code that needs to use the result should be in its own callback, which runs when the result is available. For example:
var loadRarity = function(cb) {
var rarities = [],
counter = 0,
done = function(){
if(counter++ === deck.length - 1){
cb(rarities);
}
};
for (var i =0; i < deck.length; i++) {
Card.get({cardName: deck[i].card_name}, function(data) {
rarities.push(data.data[0].rarity);
done();
});
}
};
loadRarity(function(completedRarities){
console.log(completedRarities);
});
Sample (using an image onload fn to simulate your asysnc call): http://codepen.io/RwwL/pen/VeeEBR?editors=001
I have multiply functions which are using the same cycle code and i'm wondering is it possible to simplify the code by having one cycle function so i could execute the code just by calling wanted function names.
Now:
for(var i=0;i<all;i++){ someFunction(i) }
Need:
cycle(someFunction);
function cycle(name){
for(var i=0;i<all;i++){
name(i);
}
}
I tried to do this by using "window" and i get no error but the function is not executed.
var MyLines = new lineGroup();
MyLines.createLines(); // works
MyLines.addSpeed(); // doesn't work
var lineGroup = function(){
this.lAmount = 5,
this.lines = [],
this.createLines = function (){
for(var i=0,all=this.lAmount;i<all;i++){
this.lines[i] = new line();
}
},
this.addSpeed = function (){
// no error, but it's not executing addSpeed function
// if i write here a normal cycle like in createLines function
// it's working ok
this.linesCycle("addSpeed");
},
this.linesCycle = function(callFunction){
for(var i=0,all=this.lAmount;i<all;i++){
window['lineGroup.lines['+i+'].'+callFunction+'()'];
}
}
}
var line = function (){
this.addSpeed = function (){
console.log("works");
}
}
window['lineGroup.lines['+i+'].'+callFunction+'()'];
literally tries to access a property that starts with lineGroups.lines[0]. Such a property would only exist if you explicitly did window['lineGroups.lines[0]'] = ... which I'm sure you didn't.
There is no need to involve window at all. Just access the object's line property:
this.lines[i][callFunction]();
i get no error but the function is not executed.
Accessing a non-existing property doesn't generate errors. Example:
window[';dghfodstf0ap9sdufgpas9df']
This tries to access the property ;dghfodstf0ap9sdufgpas9df, but since it doesn't exist, this will result in undefined. Since nothing is done with the return value, no change can be observed.
Without a name space use:
window["functionName"](arguments);
SO wrap it up and use it thus:
cycle(someFunction);
function cycle(name){
for(var i=0;i<all;i++){
window[name](i);;
}
}
With a namespace, include that:
window["Namespace"]["myfunction"](i);
Note that this is likely a bit of overkill but using a function to make a class object (you can google the makeClass and why it is/could be useful) you can create instances of the object.
// makeClass - By Hubert Kauker (MIT Licensed)
// original by John Resig (MIT Licensed).
function makeClass() {
var isInternal;
return function (args) {
if (this instanceof arguments.callee) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
var instance = new arguments.callee(arguments);
isInternal = false;
return instance;
}
};
}
var line = function () {
this.addSpeed = function () {
console.log("works");
};
};
var LineGroup = makeClass();
LineGroup.prototype.init = function (lineNumber) {
this.lAmount = lineNumber?lineNumber:5,
this.lines = [],
this.createLines = function (mything) {
console.log(mything);
var i = 0;
for (; i < this.lAmount; i++) {
this.lines[i] = new line();
}
},
this.addSpeed = function () {
console.log("here");
this.linesCycle("addSpeed");
},
this.linesCycle = function (callFunction) {
console.log("called:" + callFunction);
var i = 0;
for (; i < this.lAmount; i++) {
this.lines[i][callFunction]();
}
};
};
var myLines = LineGroup();
myLines.createLines("createlines");
myLines.addSpeed();
//now add a new instance with 3 "lines"
var newLines = LineGroup(3);
newLines.createLines("createlines2")
console.log("addspeed is a:" + typeof newLines.addSpeed);
console.log("line count"+newLines.lAmount );
newLines.addSpeed();
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
var roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if(roa.length > 0){
result[sheetName] = roa;
}
});
return result;
}
I have above code. How to alter it, in order to let the anonymous function run only over the first element in SheetNames? (or alternatively alter sth else in order to achieve the same result).
I got this so far, I am not sure it is correct.
...snip
var tmpArray = workbook.SheetNames.slice(0);
tmpArray.forEach(function(sheetName) {
...snip
One way is what you've mentioned, but .slice(0) returns the whole array, so use .slice(0,1) for only the first item:
var tmpArray = workbook.SheetNames.slice(0, 1);
tmpArray.forEach(function(sheetName) { /* ... */ })
But if you only want to process the first item you can cancel the forEach() and the anonymous()
totally:
function to_json(workbook) {
var result = {},
sheetName = workbook.SheetNames[0],
roa = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if(roa.length > 0) result[sheetName] = roa;
return result;
}
I have a function which is called when a file is needed to be read in a folder. In this case since i have 3 files in that folder, it is called 3 times consecutively. I need to save all files info into array mapped_data2 like that:
mapped_data2[0] = inner_data1 //first file info,
mapped_data2[1] = inner_data2 //second file info etc.
However using my code i am having just the first files information 3 times. I am a bit confused with global variables, if you can point out the problem, i would appreciate it.
here is the code:
var mapped_data = [];
var mapped_data2 = [];
function o(msg) {
if (msg.data) {
var inner_data = [];
var lines = msg.data.split('\n'); //read lines of a file
for (var i = 2; i < lines.length; i++) {
if (lines[i].length > 0) {
.. //do same data format here
inner_data.push([son, vactual, voutput]);
}
}
mapped_data = inner_data;
}
else {
if (msg.topic == "/somefolder/somefolder") {
for (var i = 0; i < msg.args.length; i++) {
var filename = msg.args[i];
aw.get(filename);
}
}
}
}
function de() { //where i wanted to use these files info
for (var i = 0; i < 3; i++) {
mapped_data2[i] = { key: "Group" + (i + 1), values: mapped_data };
}
var datam = mapped_data2;
var den = JSON.stringify(datam);
document.write(den);
};
function init() {
..//create new client called aw for the server application and start it;
..//if the connection is established:
aw.onmessage = o;
aw.get("/somefolder/somefolder"); // request list of files in a folder
};
//when html page is being onload, call the functions init() and de()
var mapped_data2 = [];
function o(msg) {
var mapped_data = []; // this doesn't need to be global
if (msg.data) {
var inner_data = [];
...
mapped_data = inner_data;
} else {
...
}
mapped_data2.push({ key: "Group" + mapped_data2.length + 1, values: mapped_data };)
// do more stuff as in den()
}
Why does it seem like my page goes in to a infinite loop when the dealHands() function is called? What should happen is, it should call the fetchCard() function. That function should create a random number between 0-51, then search the discardPile array to make sure that the random number doesn't existed within the discardPile array. If it doesn't then the fetchCard() function should return the random number back to the dealHands() function so that it can be assigned/added to the allHands array.
//Variables
var discardPile = new Array();
var allHands = new Array();
//Prototypes
Array.prototype.exists = function(search) {
for(i=0;i<this.length;i++)
if (this[i] == search) return true;
return false;
}
//Functions (Only the ones the that are needed for this question)
function dealHands() {
var cardsOfHand = new Array()
for (x=0;x<=1;i++) {
for (y=0;y<=1;y++) {
cardsOfHand[y] = fetchCard();
discardCard(cardsOfHand[y]);
}
allHands[x] = cardsOfHand
}
}
function discardCard(card) {
var totalCards = discardPile.length;
if (totalCard != 0) { totalCards++ }
discardPile[totalCards] = card;
}
function fetchCard() {
var usedCard = true;
while(usedCard == true) {
var randomCard = Math.floor(Math.random()*51);
usedCard = discardPile.exists(randomCard);
}
return randomCard;
}
you have i++ in your loop, not x++
for (x=0;x<=1;i++) {
for (x=0;x<=1;**i**++)
should be x.