Let's say I have the following for loop in Javascript (this is for Adobe Photoshop using ExtendScript):
http://prntscr.com/cx2cab
Would it be possible to rewrite this so that all six of the created created text fields are all assigned as six different variables, each with a constant name only differing by "i" as specified in the for loop? Furthermore, would it then be possible to assign all of those variables into an array within the for loop instead of writing out each variable name in the array individually? If so, how would you go about this?
You can create window variables window["num"] = "1" == var num = "1"
var p = ["I","You","We","They"];
for(var i=0;i<p.length;i++){
window[p[i]] = p[i]+" "+"Love Cacke";
}
//now you have variables I,You,We,They
console.log(I);
console.log(You);
console.log(We);
console.log(They);
/*
[
"I Love Cacke",
"You Love Cacke",
"We Love Cacke",
"They Love Cacke"
]
*/
Related
I haven't found this answer anywhere, and have been on the lookout for a few months, so my apologies if I'm overlooking something that should be obvious. Self-taught and came upon a rather vexing gap in my knowledge here.
In an rather complex yarn of connected pieces, I have two globally-scoped (basically static) variables and an array of character types outside of the main onclick function, as such:
var missingWut = ["child","spouse","talisman","relic","sock"];
var rdmmissingWut;
var pronounA = "he";
var charTypes = [
["goatherd",pronounA+" wants to find a missing goat","kind"],
["shepherd",pronounA+" wants to find a missing sheep","cruel"],
["detective",pronounA+" wants to find a missing "+missingWut[rdmmissingWut],"spidery"],
...,
..., //this goes on for awhile; the array is currently 500 items long and has way more subindexes than I wanted/needed to include in this example.
];
We've declared the variable names in the line above, but obviously rdmmissingWut is undefined at this point.
We then - for the sake of memory - go on to define rdmmissingWut inside the function, thereby updating its value from undefined to a random index number:
rdmmissingWut = Math.floor(Math.random()*missingWut.length);
rdmcharType = Math.floor(Math.random()*charTypes.length);
before assigning a random charType index to character 1 (char1).
var char1 = charTypes[rdmcharType];
My question is this -
Is there a way to update the variable value within the array - after I've updated the variable - without redefining the entire array?
One could obviously just reiterate the definition of the array, at which point it would update all variable values with their current value, but that seems really clumsy, cluttered and inefficient.
Another use case (with the same issue):
I want to use this same chartypes array to randomly roll a character type for character 2 (char2) - and eventually, char3 & char4, as well. But let's say char2 (or 3 or 4) is female. To do this, after char1 was defined, I would then need to update the value of pronounA to "she" and thereupon update the pronounA definition in every instance within the charTypes array before selecting a random charTypes index for her - correct? What is the best way to accomplish this? I'm sure there must be some elegant solution that I'm just ignorant of.
Thanks for your help.
You'll be needing to evaluate that variable every time you run through your array, so I'd recommend a placeholder that can be replaced with .replaceAll
var missingWut = ["child", "spouse", "talisman", "relic", "sock"];
var rdmmissingWut;
var pronounA = "he";
var charTypes = [
["goatherd", pronounA + " wants to find a missing goat", "kind"],
["shepherd", pronounA + " wants to find a missing sheep", "cruel"],
["detective", pronounA + " wants to find a missing _missingWut_", "spidery"]
];
function getMissingWut() {
return missingWut[rdmmissingWut || 0]; // this uses zero incase the value hasn't been updated
}
console.log(charTypes.flat().join("\n").replaceAll(/_missingWut_/g, getMissingWut()))
rdmmissingWut = 4
console.log(charTypes.flat().join("\n").replaceAll(/_missingWut_/g, getMissingWut()))
I'm creating a quiz app using Javascript and I've come across an error that is puzzling me so I decided to post it on here and maybe someone sees something different then me.
I have an object of arrays called quizQ --- inside this object is my question and answer list. It is structured like this - I should mention that testbank does get initialized into quizQ in another function in my script file and all the console.logs confirm this, so the problem must lie in the for loop
var testBank = [
{
qTitle: "Commonly used data types DO NOT include:",
picks: ["strings", "booleans", "alerts", "numbers"],
ans: "alerts"
},
{
qTitle: "The condition in an if / else statement is enclosed within ____.",
picks: ["quotes", "curly brackets", "parentheses", "square brackets"],
ans: "parentheses"
},
{
qTitle: "Is JavaScript fun to work with?",
picks: ["No", "Sometimes", "What is Javascript", "Not just yes, but HELL YES!"],
ans: "Not just yes, but HELL YES!"
},
{
qTitle: "DOM is an abreviation for ____",
picks: ["Data Object Mode", "Dumb Old Man", "Document Object Model", "Dutle Opo Mipsy"],
ans: "Document Object Model"
},
--- Pretty simple questions I pulled from another app on Github. So what I've done is created a function that will put these picks in a list so I can choose the one I want to answer with. I use the qTitle as the header for each question and after you complete it you are presented with another. ---
The problem is when I run the function and I run the for loop for it, it keeps telling me It cannot read undefined of '0' which is the first index the for runs over. Here is my code
current = quizQ.pop();
console.log(current)
let questionServed = document.createElement('h2');
questionServed.setAttribute("question", current.qTitle);
questionServed.textContent = current.qTitle;
testEl.appendChild(questionServed)
let choices = document.createElement('ul');
choices.setAttribute('id', 'choices');
testEl.appendChild(choices)
for (let i = 0; i < current.picks.length; i++) {
let pickList = document.createElement('li')
pickList.setAttribute('pick-value', current.pick[i]);
pickList.setAttribute('id', 'questionNum' + i);
pickList.textContent = current.pick[i];
choices.appendChild(pickList)
}
I've console.log(current) and it returns the last array in the testBank as expected, however when the for loop runs, it keeps giving me the error mentioned above. I assume I'm writing the statement incorrectly current.pick[i] but I assumed that it would go into current, then picks, and pull out the pick[0] which would be one of the options given.
Any help would be greatly appreciated!
A good plan to avoid this is to have a convention that arrays are named with a plural
In your case the problem is pick versus picks.
for (let i = 0; i < current.picks.length; i++) {
let pickList = document.createElement('li')
pickList.setAttribute('pick-value', current.picks[i]);
pickList.setAttribute('id', 'questionNum' + i);
pickList.textContent = current.picks[i];
choices.appendChild(pickList)
It is often difficult to remember whether the array is picks or pick. After all, when you select one element, you think to yourself that you are selecting element #3, so why shouldn't it be called pick[3]?
A convention to avoid this is that the array should be called picks, and an individual value from the array, if you need to extract it as a single item, you can call pick.
Sticking to this convention makes it easier to avoid the problem.
It's likely a typo with current.pick. Ensure all members are named correctly and consider using Typescript for future error checking.
https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
The description of Javascript function parameters on W3Schools wasn't very clear, so I just want to clarify.
From my understanding, there isn't a type restriction; the "real value" of the parameters are passed into the method. Is there a way to pass objects or elements? Or is that what is meant by "real value"?
For example:
The function displayText meant to take input text and set a display to show a new word in the given input text, going to the next word every time it's called.
function displayText() {
var text = document.getElementById("words").value;
// Since text is initialized
// every time the method is called,
// it will always start at the beginning of the text area.
// Not sure how to fix this since making `text`
// a global variable doesn't work
var list = text.split(/[ \t\n]+/);
displayNext(list, "display");
}
There is a "helper" method, displayNext, which is supposed to shift to the next word in the list and sets the display to that word.
function displayNext(list, textboxID) {
document.getElementById(textboxID).innerHTML = list.shift();
}
This isn't working as it is intended. I'm fairly sure it's because I've mucked up something with the parameters, since displayNext sets innerHTML to null. list must have not passed properly. I'm not sure how to fix this.
I'm sure there's a more efficient way to do this, but this is a good opportunity to learn how Javascript parameters actually work, so I thought I'd ask.
JSFiddle
Based on the comments in your code, it sounds like you want displayText() to display the "next" word each time. To do that, you have to create some place to store some state about which word is the next one to display. As you have it now, you create a new array every time and always display the first word.
The simplest way is to create a variable outside your function in some lasting scope where you store the word number:
var wordNum = 0;
function displayText() {
var text = document.getElementById("words").value;
var list = text.split(/\s+/);
if (list.length !== 0) {
// make sure we aren't off the end of the list
wordNum = wordNum % list.length;
displayNext(list[wordNum++], "display");
}
}
function displayNext(text, textboxID) {
document.getElementById(textboxID).innerHTML = text;
}
For a lot more info about arguments to Javascript functions and even how you can detect what arguments were passed or overload arguments, see this answer: How to overload functions in javascript? and for more info about how arguments are passed: Javascript by reference vs. by value
So Im looking for help for writing a simple function in javascript. What I am trying to do is create an array of 6 name and print only those ending in "ie" or "y".
Here is my code - any help is appreciated. It unfortunately never reaches the function :(
//An array of names
var nameList = new Array("Freddie", "Mary", "Thomas", "Suzie", "Terry", "Kevin");
//Prints names before searching
document.write(nameList);
function e_names(nameList) {
for (var index = 0; index < arrayList.length; index++) {
var name = arrayList[index];
if (name == /\bie\b/ || name == /\by\b/)
document.write("",name, " </ br>");
index++;
} //End of for loop
} //End if method
Use /(ie|y)$/ ($ is used to match the end) to test it:
if (/(ie|y)$/.test(name))
It unfortunately never reaches the function :(
In your code, you are defining a function but then never executing it. Execute it like so:
e_names(namesList);
The loop has a bug:
for (var index = 0; index < arrayList.length; index++) {
arrayList is not defined, at least not in this code. It could be a previously defined or global variable, but then why does the function take a parameter called nameList? I think this is a simple typo.
if (name == /\bie\b/ || name == /\by\b/)
I am not sure what it means to equal a regular expression, but I would hazard a guess it won't do what you want. I think you want the .test function such as:
if (/\bie\b/.test(name) || /\by\b/.test(name))
Your pattern includes \b, the word boundary both before and after the y or ie. Therefore, it will only match strings that have i or ie as exact strings or with spaces around them. They won't match array or key or cookie. I think you meant to anchor them to end of string as suggested by #xdazz's answer. He even OR'ed the two expressions together for you:
if (/(ie|y)$/.test(name))
Finally, you double-increment index:
index++;
This will only iterate over "Freddie", "Thomas", and "Terry" because you increment twice. The index++ at the end of the loop construct is sufficient. Take this line out.
Altogether now:
//An array of names
var nameList = [ "Freddie", "Mary", "Thomas", "Suzie", "Terry", "Kevin" ];
//Prints names before searching
document.write(nameList);
function e_names(names) {
for (var index = 0; index < names.length; index++) {
var name = arrayList[index];
if (/(ie|y)$/.test(name)) {
document.write("",name, " </ br>");
}
} //End of for loop
} //End if method
e_names(nameList);
Note that I renamed the parameter so that it doesn't cause confusion with scoping and I also put curly braces around your if block. I usually don't change other people's code style, but I felt it was needed in this case to make it clearer.
I also changed the array construction to use the literal notation. Much debate has been had around the new Array constructor. It's probably safe for this example, but if there is a single element or the array contents are dynamic, it gets confusing. For example, what does new Array(17) mean? It means create an array with 17 null references in it. It does not create an array with the number 17 in it. For that reason, my advice is to use the [ ] syntax. For details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
There are two JSON var (JSON.parse'd already)
var acc http://pastebin.com/7DyfFzTx
var sit http://pastebin.com/vnZiVaDx
My objective is to loop each var to compare acc.items.site_name with sit.items.main_site.name to see if they are equal. If they are equal, then I need to store sit.items.main_site.site_url in a variable. I am using this code:
for(i=0; i < acc.items.length;i++)
{
aname = acc.items[i].site_name;
for(i=0; i < sit.items.length;i++)
{
sname = sit.items[i].main_site.name;
if (aname == sname)
alert("same "+aname);
}
}
But the alert only logs "same Physics" . "Physics" is the first object in acc.items. This means that the loop is only comparing first acc.items but how do I make it compare the second and further on objects (e.g. "TeX - LaTeX")
Well, you can start by using a different control variable for the outer and inner loops. :)
Also, notice how you are running through every element of the second object each time you consider an element in the first object- that doesn't seem like what you want to do.
Try reviewing this posting for a more modular method:
http://jsperf.com/recursive-vs-json-object-comparison
You're using the same variable for the inner and outer loop.
Give the second for loop a different variable name than i