["var"+1]=someValue - Can something like this be done? - javascript

function giveValue(n){
["r"+n]=5;
}
giveValue(10);
You get the idea.
The point is that I have a handful of variables with similar name, varying only in a number at the end. Using a switch statement is fine with a few variables a few times, but for this particular project it is driving me crazy. I know I can do:
var r2="lol";
var someVar=eval("r"+2);
//someVar=="lol"
And I was wondering if I can do something like this but with the dynamic reference to the left of an assignment.
Is it possible?

If you REALLY want to do that, this should work:
function giveValue(n){
window['r'+n] = 5;
}
giveValue(10);
console.log(r10)
But please, DON'T DO IT!
You really should use arrays!

The best way is to create an array called r:
var r = [];
r[2] = 5;

Related

Create a re-usable type writer effect function in Javascript?

I know the basics of what I need to do here, but my attempt at coding it is riddled with problems so here is what I want to do.
Define a series of strings to be called up into a function that types it onto the screen with a slight delay between each letter.
I've found some examples of people making typewriter title cards, but these are not designed to be used like functions that can be called up on the fly. For this particular project, we need the text to function like a makeshift dialog system that won't be called up until the function is called with a specific string.
Like a button with " onclick="dialogFunction(idOfStringToBeTyped) "
what I have looks like this:
var d1Example = "Hello, I am example dialog";
function dialog(dialogString) {
var i;
for (i = 0; i <= dialogString.length(); i++) {
document.write( dialogString.charAt(i) );
java.lang.Thread.sleep(50);
}}
So my attempts to code the content has been... brute force-y...
EDIT: to include my attempt, should have been there in the first place, sorry about that.
This, in theory, should work, but in practice does nothing. I probably have a syntax error. but really it doesn't make sense to me why this doesn't work.
You should look into the JavaScript functions setTimeout and Math.random().
You can use Math.random() to create a floating point integer between 0 and 1.
var multipule = 5
var rand = Math.random(); // 0.5680401974599227
var randInSeconds = rand * multipule // 2.840200987299614
var waitInSeconds = Math.round(randInSeconds) // 3
Then use the the setTimeout out method to call the code that writes each character. setTimeout takes two parameters, a function and the number of seconds:
var writeCharacter = function(){
...
};
setTimeout(writeCharacter, 300);
I'll leave it to you to work out all the timing.

JavaScript: shorthand for conditionally adding something to an array

I am writing a Mocha test for a server at work.
I get two potential phone numbers for a customer, at least one of which will be defined.
var homePhone = result.homePhone;
var altPhone = result.altPhone;
I want to use underscore's _.sample function to pick one of these at random. However, one of them may be undefined.
So what I was thinking was something like:
//pseudocode
var phone = _.sample([homephone || (doNothing), altphone || (doNothing)]);
the _.sample function looks like this:
http://underscorejs.org/#sample
the problem of course, is there is no shorthand syntax that I know of to conditionally add something to an array.
The verbose way to do what I want is:
var phoneArray = [];
if(homePhone){
phoneArray.push(homePhone);
}
if(altPhone){
phoneArray.push(homePhone);
}
var phoneSelection = _.sample(phoneArray);
is there a more elegant way to do this in JavaScript?
You could use .filter:
_.sample([homephone, altphone].filter(_.identity))
Another way would be:
_.sample([homephone, altphone]) || homephone || altphone;
Since you're already using underscore, I would suggest leveraging compact:
var phone = _.sample(_.compact([homephone, altphone]));
This is basically a shortened version of dave's answer, since compact is literally implemented as function(array) { return _.filter(array, _.identity); }.
What about:
var phone = (homephone && altphone)? _.sample([homephone, altphone]) : (homephone || altphone);
Array literals in JavaScript:
[ 1, 2, 3 ]
...are a way to statically declare which things go in which positions in an array. In other words, when you write the code, you already know where things will go.
In your scenario, the positions are only known dynamically. In other words, you don't know where they'll go until you run the program on a given set of inputs.
So basically what you're asking for is impossible, barring any radical changes to how array literals work in future versions of JS. However, if all you want is to save typing, #dave's answer is pretty nice. I'm mainly just clarifying that array literals by themselves don't have this capability.

Javascript Function arguments as variables

Firstly i would like to note this is my first time using this site so if I do something incorrectly, i am sorry. Secondly i am intermediate at JavaScript but have only been truly been coding with for 3 days and am using it in an incremental game (more for myself to learn than others as there are quite a few out there). I've been doing pretty good and learning more as i go.
My problem is that I've gotten stuck using a function with arguments, my code looks like this:
<button onClick="getStorg(gargAmm,'gargAmm')"> Get Garage </button>Ammount: <span id="gargAmm">0<br />
Which is the HTML that launces the Function:
var gargAmm = 0;
function getStorg(buildAmm,buildID)
{
buildAmm = buildAmm + 1;
document.getElementById(buildID).innerHTML = buildAmm;
}
The display will make the "Amount:" go up to one when the button is first clicked, but then stalls. I've tried rearranging all sorts of variables and such but i just don't know why this doesn't work. Can anyone help?
What you're doing is you're using the Global variable value
var gargAmm = 0;
Whenever you call the function it uses the same value as zero and increments it.
So your getting the value as 1 and its not incrementing further.
I have tried an another approach to solve your issue have a look at it.
<button onClick="getStorg('gargAmm')">
Get Garage
</button>Ammount: <span id="gargAmm">0</span><br />
Here is the javascript
function getStorg(buildID)
{
var d= document.getElementById(buildID);
var t= parseInt(d.innerText);
t=t+1;
document.getElementById(buildID).innerHTML = t;
}
Here the text from the span is taken and converted to int and then incremented the value
and inserted back into span.
Here is the Working fiddle http://jsfiddle.net/p8E4G/
Simple:
function myFunc(a,b) {
b = b || 0;
// b will be set either to b or to 0.
}

Array adds dimension when randomized

Allo'
I'm working on a little project of mine and part of it involves taking a two dimensional array already created and randomizing it.
So I have something which looks like this:
foo = [[1,2],[3,4],[5,6],[7,8]];
randomizeFoo = function(){
var randomizedFoo = [];
newFoo = foo;
for(i = 0; i < newFoo.length; i++){
count = Math.random() * newFoo.length;
randomizedFoo.push(newFoo.slice(count, count + 1));
}
return randomizedFoo;
};
This does indeed randomize the array but I end up with something like this:
randomizedFoo = [[[7,8]],[[1,2]],[[5,6]],[[3,4]]]
My nice neat 2D array is now a 3D array with the lowest level arrays now burred under an extra level. I realize that this is not really that big a deal and the rest of my code just needs to compensate but it bugs me for 2 reasons:
It's extra complexity and that's never good.
I don't like my code doing things without me knowing the reason why.
Anybody have any ideas as to why it's doing this? I put a 2D array in, I want a 2D array back out again.
It's because you are using slice. Just use count as the index into foo. As in : randomizedFoo.push(foo[count]);
Make sure you make count an int first.
You can take the script from this answer and use map with it:
foo = range(0, foo.length-1, true).map(function(i) {
return foo[i];
});
Demo: http://jsbin.com/ayepeh/1/edit (ctrl + enter to refresh)

Google Docs - spreadsheet loop

This one might be a bit basic and easy to answer, but I've been pulling out my hair for a while now!
I've built the following code - which is semi-pseudo as I can't find the right way to make things work!
var s = "Test";
function onEdit(event)
{
var ss = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if (ss.getName() == s)
{
results = {"Currently On": 0, "Next Up": 0, "On Hold": 0, "Waiting on someone else": 0, "zDone": 0};
last = ss.getMaxRows();
start = ss.getRange("F3:"+last).getValues();
var output = "J11";
for (x=0;x<start.length;x++)
{
results[start[x]]++;
}
for (y=0;y<results.length;y++)
{
row = ss.getRow(output);
row.value = results[y];
output++;
}
}
}
I've got an example of the data in this image
The basic idea is to run through all the possible categories of each task and keep a numeric list on the side of how many of each there are. I'd also like to make it dynamic (so I don't have to hard code in the list of categories) but I'm more interested in just making it work for the moment.
The Google Apps debugger is very frustrating!
Thanks for your help all!
Firstly, this particular use case would be easily achievable with a spreadsheet formula, eg:
=QUERY(A2:F;"select F, count(A) where F != '' group by F label count(A) 'Count'";1)
but there may be a reason why you want to do this with GAS.
So secondly, this is where I think there may be some syntax issues:
last = ss.getMaxRows();
I would just use var last = ss.getLastRow() here.
start = ss.getRange("F3:"+last).getValues();
The range reference would evaluate to something like "F3:100", which is a valid reference in GSheets (don't know about whether GAS can handle it), but nevertheless you really want something like "F3:F100", so I would use var start = ss.getRange("F3:F"+last).getValues();.
results[start[x]]++;
When you create an array from a getValues() call it is a 2D array, so you would need to use results[start[x][0]]++;.
With the next loop and the output variable, I must admit I'm a bit lost with what you're doing there. How did you want your result table laid out?
You have
output = "J11";
And then you do
ss.getRow(output);
output++;
This is invalid.First of all, ss is a Sheet under which there is not getRow method. So, what you should really be doing is something like this
var row = 11 ;
var col = 10 ; //Col J
for (y=0;y<results.length;y++)
{
ss.getRange(row,col,1,1).setValue(results[y]);
row++:
}
Like AdamL, I suggest that this is better handled within the native capability of the spreadsheet. Seems to me that you want a pivot table, which would update dynamically. Alternatively a formula like =countif(F:F,"Currently On" ) would meet your immediate request. =Unique(F:F) will give you the list of categories in an array

Categories

Resources