I am new to javascript and would really appreciate some help. The javascript below is connected to two buttons in an an html documented called "next" and "previous". The buttons are intended to allow a user to scroll forwards and backwards through an array that contains the letters of the alphabet. The code is almost working, but has one bug. Clicking the "next" button will display the next letter in alphabet (i.e. B will switch to C). However, clicking the "previous" button will display the next letter in the alphabet before changing directions. For example, if the letter "C" is displayed, clicking "previous" will display "D" and then "C", "B", "A", "Z", etc...
What changes need to be made to the code below to fix this problem? If a letter is displayed, I would like for the function "next" to return the next letter and for the function "previous" to return the letter that comes immediately before the letter being displayed.
function next(){
let upperCase = ["A","B", "C", "D", "E","F", "G", "H", "I","J", "K", "L", "M","N", "O", "P", "Q","R", "S", "T", "U","V", "W", "X", "Y","Z"];
document.querySelector(".item-2").innerHTML = upperCase[index++];
if(index > upperCase.length - 1)
index = 0;
}
function previous(){
let upperCase = ["A","B", "C", "D", "E","F", "G", "H", "I","J", "Q", "L", "M","N", "O", "P", "Q","R", "S", "T", "U","F", "W", "X", "Y","Z"];
document.querySelector(".item-2").innerHTML = upperCase[index--];
if(index < 0)
index = upperCase.length - 1;
}
You need to set ++ and -- before the index variable in order to return its value after incrementing it:
let index = 0;
const previousButton = document.getElementById('previous');
const nextButton = document.getElementById('next');
previousButton.addEventListener('click', previous);
nextButton.addEventListener('click', next);
const upperCase = ["A","B", "C", "D", "E","F", "G", "H", "I","J", "K", "L", "M","N", "O", "P", "Q","R", "S", "T", "U","V", "W", "X", "Y","Z"];
function next(){
if(++index > upperCase.length - 1)
index = 0;
document.querySelector(".item-2").innerHTML = upperCase[index];
}
function previous(){
if(--index < 0)
index = upperCase.length - 1;
document.querySelector(".item-2").innerHTML = upperCase[index];
}
<div class="item-2"></div>
<button id="previous">Previous</button>
<button id="next">Next</button>
Related
I'm trying to push to an initially empty array with the condition that the content at two different indexes of two different non-empty arrays don't have the same character and the initially empty array has not already pushed that character earlier
I've tried using the not operator, contains, includes, but nothing seems to work.
var pushToArray = [];
for (var i = 0; i < 5; i++) {
var characters = ["M", "U", "S", "I", "C"];
var moreCharacters = ["F", "R", "I", "E", "N", "D", "L", "Y"];
randomIndex = Math.floor(Math.random() * moreCharacters.length);
// && push to 'pushToArray' if the character is not in 'pushToArray'
if (characters[i] != moreCharacters[randomIndex] && !pushToArray.includes(moreCharacters[randomIndex])) {
pushToArray.push(moreCharacters[randomIndex]);
}
if(arrayContent1("I") == arrayContent2("I")) then don't push
Sample expected results for pushToArray:
["F", "R", "E", "D", "L"]
Sample actual results for pushToArray:
["I", "F", "R", "D", "Y"] I don't want that letter 'I' in there
The test
if (characters[i] != moreCharacters[randomIndex]
will fail only if characters[i] is the picked character - it sounds like you want to make sure that none of the characters match the picked character:
if (!characters.includes(moreCharacters[randomIndex])
If you're only conditionally pushing to the array, then change the for loop to
while (pushToArray.length < 5) {
var pushToArray = [];
while (pushToArray.length < 5) {
var characters = ["M", "U", "S", "I", "C"];
var moreCharacters = ["F", "R", "I", "E", "N", "D", "L", "Y"];
randomIndex = Math.floor(Math.random() * moreCharacters.length);
// && push to 'pushToArray' if the character is not already in there
if (!characters.includes(moreCharacters[randomIndex]) && !pushToArray.includes(moreCharacters[randomIndex])) {
pushToArray.push(moreCharacters[randomIndex]);
}
}
console.log(pushToArray);
But, the logic would be easier to follow if you filtered the characters out of moreCharacters beforehand:
const excludeChars = ["M", "U", "S", "I", "C"];
const inputChars = ["F", "R", "I", "E", "N", "D", "L", "Y"]
.filter(char => !excludeChars.includes(char));
const result = [];
for (let i = 0; i < 6; i++) {
const randIndex = Math.floor(Math.random() * inputChars.length);
const [char] = inputChars.splice(randIndex, 1);
result.push(char);
}
console.log(result);
This code does this:
I would like array3 to only have letters from array2 that are not in array1. I basically don't want any letters that exist in array1
var characters = ["M", "U", "S", "I", "C"];
var moreCharacters = ["F", "R", "I", "E", "N", "D", "L", "Y"];
var pushToArray = [];
var i, l = characters.length;
for (i = 0; i < l; i++) {
randomIndex = Math.floor(Math.random() * moreCharacters.length);
// && push to 'pushToArray' if the character is not in 'pushToArray'
if (!characters.includes(moreCharacters[randomIndex]) && !pushToArray.includes(moreCharacters[randomIndex])) {
pushToArray.push(moreCharacters[randomIndex]);
}
}
console.log(pushToArray);
This can be simply achieved by doing:
var characters = ["M", "U", "S", "I", "C"];
var moreCharacters = ["F", "R", "I", "E", "N", "D", "L", "Y"];
var pushedToArray = [...characters].filter(x => moreCharacters.indexOf(x) === -1);
var finalArray = pushedToArray.filter((item, index) => pushedToArray.indexOf(item) === index);
I'm making a guessing game for class. I pretty much have it done, but the biggest problem I've had was making the string randomize itself after the game ends. It picks a random letter if the page refreshes but the objective is to keep track of stats so refreshing is out.
Here's my javascript code:
var lettersChar = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
function randomFunc() {
var randomMath = lettersChar[Math.floor(Math.random() *
lettersChar.length)];
return randomMath;
}
//variables
var randomChar = randomFunc();
//array where user input will be stored
var userChoices = [];
var wins = 0;
var losses = 0;
var guesses = 9;
//keypress event
document.onkeyup = function (event) {
var userGuess = event.key;
var userOptions = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
"z"];
//if guess is correct, +1 to win and refresh game and generate new letter
if (userOptions.indexOf(userGuess) > -1) {
if (userGuess === randomChar) {
wins++;
guesses = 9;
randomFunc();
console.log(wins);
}
//if guess is incorrect, then print wrong guess and -1 to guesses left
else if (userGuess !== randomChar) {
guesses--;
userChoices.push(userGuess);
}
//If guess reaches to 0 add +1 to loss and restarts game
if (guesses === 0) {
losses++;
guesses = 9;
userChoices = [];
randomChar;
}
}
I've tried invoking the function and it doesn't appear to work for me at this moment. Any help is appreciated!
See the last line you posted:
randomChar;
You're just declaring randomChar again and not doing anything with it. If you want to randomize it after the game ends, you should call randomFunc again:
randomChar = randomFunc();
Same for when the user wins: replace with
if (userGuess === randomChar) {
wins++;
guesses = 9;
randomChar = randomFunc();
console.log(wins);
}
dft=["t", "h", "i", "s", "I", "s", "S", "p", "i", "n", "a", "l", "T", "a", "p"];
ans=[4, 6, 12, -1];
for(x=0;x<ans-1;x++){
dft.splice(ans[x],0,"-");}
return dft;
I am trying to return an array that has "-" placed into the dft array using the indexes in the ans array except the -1 index.
result im getting is ["t", "h", "i", "s", "I", "s", "S", "p", "i", "n", "a", "l", "T", "a", "p"]
this is the codepen i am working on
Firstly, it's not doing anything because your for loop end condition should be checking the loop parameter x against the length of the ans array, i.e. x < ans.length -1. Secondly, since splice is changing the array, your ans indices will be incorrect after you insert the first hyphen, so you should do it in reverse order like so:
dft = ["t", "h", "i", "s", "I", "s", "S", "p", "i", "n", "a", "l", "T", "a", "p"];
ans = [4, 6, 12, -1];
for (x = ans.length - 2; x >= 0; x--) {
dft.splice(ans[x], 0, "-");
}
console.log(dft);
We start at the end of the array, which would be ans.length - 1, except you want to skip the last element, so we start at ans.length - 2. Remember though that this assumes that the last element should be ignored.
You can reach your desired result with Array#reduce.
let dft = ["t", "h", "i", "s", "I", "s", "S", "p", "i", "n", "a", "l", "T", "a", "p"];
let ans = [4, 6, 12, -1];
let res = dft.reduce((s,a,i) => {
(ans.indexOf(i) > -1) ? s.push(a, '-') : s.push(a);
return s;
}, []);
console.log(res);
Arrays do not have a numeric primitive, so you want your for loop condition to read x < ans.length.
Your index also needs to be ans[x] + x, because each splice() is increasing the length of the array by 1.
These changes alone should accomplish your stated goal. However I would also add:
you should be declaring variables purposefully, rather than using implicit globals.
you can replace your for loop using the forEach() method, which can make your intention more clear.
you probably want spacing around terms and operators, which also helps readability.
You need to sort the index array and do in the reverse order otherwise it would change the index of other elements.
var dft = ["t", "h", "i", "s", "I", "s", "S", "p", "i", "n", "a", "l", "T", "a", "p"],
ans = [4, 6, 12, -1];
// sor the array to place - at the last higher index first
ans.sort(function(a, b) {
return a - b;
});
// get array length
var x = ans.length;
// iterate upto index reach to 0 or reaching to -1
while (x-- && ans[x] > -1) {
dft.splice(ans[x], 0, "-");
}
console.log(dft);
Just for completeness, a solution with Array#reduceRight
var array = ["t", "h", "i", "s", "I", "s", "S", "p", "i", "n", "a", "l", "T", "a", "p"],
indices = [4, 6, 12, -1],
result = indices.reduceRight((r, i) => (~i && r.splice(i, 0, '-'), r), array);
console.log(result.join(''));
I'm trying to sort a paragraph alphabetically, not according to the normal ABC but a made-up one (var order).
I wrote this function and it works great, but only for the first letter of each word - not in-word sorting as well (for example, in correct ABC 'banana' would come before 'birthday').
I'm not sure where to go from here.
$("#send").click(function () {
var text = $("#text").val().replace(/[^A-Za-z0-9_\s]/g, "").toUpperCase().split(" ");
var order = ["Q", "B", "K", "D", "H", "V", "Z", "E", "F", "O", "G", "L", "M", "S", "N", "P", "I", "X", "A", "R", "W", "U", "C", "J", "T", "Y"];
var i, t, j;
var newText = []; // will hold the new alphabet
// function to sort the words:
for (i = 0; i < order.length; i++) {
for (t = 0; t < text.length; t++) {
var firstChar = text[t][0];
if (order[i] == firstChar) {
newText.push(text[t]);
}
}
}
console.log(newText.join(','));
});
EDIT:
An example input can be: "Hi dan don't you think that this is awesome",
and I want the output to be: "don't dan hi is awesome this think that you".
You could use an object with the index of the letters and use Array#sort with a callback which looks for every letter adn calculates the order.
function foo(text) {
var text = text.replace(/[^A-Za-z0-9_\s]/g, "").toUpperCase().split(" "),
order = "QBKDHVZEFOGLMSNPIXARWUCJTY",
ref = {};
order.split('').forEach(function (a, i) { ref[a] = i + 1; });
text.sort(function (a, b) {
var i = 0, v;
do {
v = (ref[a[i]] || 0) - (ref[b[i]] || 0);
i++;
} while (!v)
return v;
});
console.log(text.join(', '));
}
foo('a aa ab b ba bb');
foo('banana birthday');
The problem with your algorithm is that it only compares the first letter in each word, but if the letters are the same the algorithm needs to compare the next letter in each word. Here's a solution that uses recursion:
function doSort(inputArr) {
var words = inputArr.slice(0);
var alphabet = ["Q", "B", "K", "D", "H", "V", "Z", "E", "F", "O", "G", "L", "M", "S", "N", "P", "I", "X", "A", "R", "W", "U", "C", "J", "T", "Y"];
words.sort(function(item1, item2) {
return sortRecursive(item1, item2, 0);
});
function sortRecursive(item1, item2, idx) {
if (item1.length <= idx && item2.length <= idx) {
return 0;
} else if (item1.length <= idx) {
return -1;
} else if (item2.length <= idx) {
return 1;
} else if (item1[idx] == item2[idx]) {
return sortRecursive(item1, item2, idx+1);
} else {
return alphabet.indexOf(item1[idx].toUpperCase()) - alphabet.indexOf(item2[idx].toUpperCase());
}
}
return words;
}
var arr = ["banana", "quebec", "bird", "birthday", "birdman", "bird"];
var sortedArr = doSort(arr);
console.log('unsorted',arr);
console.log('sorted', sortedArr);
https://jsfiddle.net/2qgaaozo/
I realize that this has been asked a million times... but sorting through all the ones I've found, I haven't found one that really explains it well.
HTML:
<div id="alphabet"></div>
JS:
var alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
"p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
var target = document.getElementById('alphabet');
for (i = 0; i < 26; i++) {
var newLink = document.createElement('div');
target.appendChild = newLink;
newLink.innerHTML = alphabet[i];
}
alert(alphabet);
alert(newLink);
alert(target);
Obviously there is something I'm missing... With such a simple example I can't believe I'm having this much trouble. Any help is much appreciated, thanks in advance!
Basically node.appendChild(node) is a function.
target.appendChild(newLink);
And your full code would be,
for (i = 0; i < 26; i++) {
var newLink = document.createElement('div');
newLink.innerHTML = alphabet[i];
target.appendChild(newLink);
}