If/Else Statements, and unintended String Concatenation - javascript

novice programmer here.
I'm currently working on a project that pumps integers into a text field, yet decided to run the array through a for loop which shoves each item into a string that's more presentable for the user. The for loop, however, is displaying this in the console.log:
2 + 1 + 4 + 1 +
Bit of clarification - it's a dice roller. The for loop segment of this click event is below, and I don't know how to specify to concatenate the last array item to not include a "+" but a "=" instead.
let diceString = '';
for (let i = 0; i <= d4Array.length; i++) {
if(i == d4Array.length) {
diceString += d4Array[i] + ' =';
break;
}
else {
diceString += d4Array[i] + ' + ';
}
console.log(diceString);
}

Your for loop iterates over 5 items in your old code. d4Array.length will be 4, but since the index starts at 0 it will iterate over 5 items before i reaches 4 ( 0,1,2,3,4 ). That is why your last item returns undefined. You can fix this by replacing let i = 0; i <= d4Array.length; i++ with let i = 0; i < d4Array.length; i++.
To select the last item i would have to be the length of the array minus one for the same reason. Thus turn i === d4Array.length into i === d4Array.length - 1
d4Array = [2,1,4,1];
let diceString = '';
for (let i = 0; i < d4Array.length; i++) {
if(i === d4Array.length - 1 )
diceString += d4Array[i] + ' =';
else
diceString += d4Array[i] + ' + ';
console.log(diceString);
}

Related

For loop to check the first letter in an array

I am trying to use a for loop to loop through an array and check the first letter of each word in the array and check to see if it starts with an M, but I can't seem to figure out how to correctly set that up.
So far I have this:
for (var animalsName = cats[0]; animalsName <= cats; animalsName++){
if (animalsName.charAt(0) == 'M') {
console.log("No treat for " + animalsName + ".");
} else {
console.log(animalsName + " loved their treat!");
}
}
You are very close.
I have made minor change in the for loop to iterate correctly and fetch the first character of the animal name.
var cats = [];
cats.push('mname1');
cats.push('tname1');
cats.push('mname2');
cats.push('Mname3');
for (var index = 0; index < cats.length; index++){
var animalsName = cats[index];
if (animalsName.substr(0,1).toLowerCase() === 'm') {
console.log("No treat for " + animalsName + ".");
} else {
console.log(animalsName + " loved their treat!");
}
}
for (let i = 0; i < cats.length; i += 1) {
if (cats[i].charAt(0).toLowerCase() === 'm') {
// do whatever you want
}
}
This will loop over the cats array and check the first letter--charAt(0)--of each element in the array. If the first letter, converted to lower case, is 'm', then you do whatever you want.

Nested Loop to add numbers

I am currently trying to create a double nested loop that adds a number to itself, given the number of instances you want it to be added by.
So when you input something in the Number, for example "5" and you input "3" for the number of instances, then the following would be printed:
5=5
5+5=10
5+5+5=15
More information on my JsFiddle
<div>
<h2>Loop</h2>
Number
<input type='text' id='tbox'>
<br>
Number of Instances
<input type='text' id='theNumber'>
<button onclick=doubleLoop;>
Add Numbers.
</button>
</div>
<div id="content">
</div>
<script>
function doubleLoop(){
var theText = document.getElementById('tbox').value;
var theNumber = document.getElementById('theNumber').value;
var content = document.getElementById('content');
content.innerHTML = '';
for (var i = 0; i < theNumber; i++) {
content.innerHTML = content.innerHTML + (i + 1) + ')';
//start of the second part of the Double Loop
for (var j = 0; j < (i + 1); j++){
if (i === 0){
content.innerHTML = content.innerHTML + theText + '=' + theText + '<br>';
} else if (i > 0) {
content.innerHTML = content.innerHTML + theText.repeat(j) + '=' + (theText * (i+1));
}
}
}
}
</script>
Here you go
https://jsfiddle.net/mkarajohn/qkn2ef4L/
function createString(number, times) {
/*
* We will create each side of the equation separately and we will concatenate them at the end
*/
var leftSide = '',
rightSide = '',
i;
for (i = 1; i <= times; i++) {
leftSide += number.toString();
if ((times > 1) && (i < times)) {
leftSide += '+';
}
}
rightSide = number * times
return (leftSide + '=' + rightSide);
}
function loop(){
// .value returns a string, so we make sure the values are converted to integers by calling parseInt()
// See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt
var theText = parseInt(document.getElementById('tbox').value);
var theNumber = parseInt(document.getElementById('theNumber').value);
var content = document.getElementById('content');
var output = '';
content.innerHTML = '';
for (var i = 1; i <= theNumber; i++) {
output += createString(theText, i);
output += '<br />'
}
content.innerHTML = output;
}
var button = document.getElementById('run');
run.addEventListener('click', loop);
If there is something that is not clear feel free to ask.
EDIT: If you are hell bent on doing it with two nested loops, here's how it would go:
function loop(){
// .value returns a string, so we make sure the values are converted to integers by calling parseInt()
// See https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/parseInt
var theText = parseInt(document.getElementById('tbox').value);
var theNumber = parseInt(document.getElementById('theNumber').value);
var content = document.getElementById('content');
var output = '';
var leftSide = '',
rightSide = '';
content.innerHTML = '';
for (var i = 1; i <= theNumber; i++) {
leftSide = '';
for (var j = 1; j <= i; j++) {
leftSide += theText.toString();
if ((i > 1) && (j < i)) {
leftSide += '+';
}
}
rightSide = theText * i;
output += (leftSide + '=' + rightSide);
output += '<br />'
}
content.innerHTML = output;
}
var button = document.getElementById('run');
run.addEventListener('click', loop);
First things first: You're naming your variables very poorly, it's really difficult to understand what you're trying to do, specially when you don't say what you want directly in the question. doubleLoop says how your function works but not what it does. getMultiplicationProcess would have been a better name. Also, you could be passing the values as arguments and just returning the result, it would look A LOT better.
Anyway, I couldn't figure how you were trying to achieve this. I've renamed your variables and did everything my way. Never name a variable theNumber or theText because doing so says nothing about what information it holds. You could have named them firstInput and secondInput but even that way it would not be clear.
Here's the code, scroll down for explanation:
var submit = document.getElementById("submit"),
firstInput = document.getElementById("tbox"),
secondInput = document.getElementById("theNumber"),
answerField = document.getElementById("content");
submit.addEventListener("click", function () {
answerField.innerHTML = getMultiplicationProcess(Number(firstInput.value), Number(secondInput.value), "<br/>");
});
function getMultiplicationProcess(multiplicand, multiplier, lineBreak) {
var result = "";
for (var i = 0; i < multiplier; ++i) {
for (var j = 0; j < i + 1; ++j) {
if (i === j) {
result += multiplicand + " = " + (multiplicand * (i + 1));
} else result += multiplicand + " + ";
}
result += lineBreak || "\n";
}
return result;
}
JSFiddle
Explanation:
The outer for loop runs as many times as the second input, or multiplier. So if you input 5 and 3 respectively this loop will run three times. It represents each line of the resulting string.
The inner loop runs as many times as the current iteration number of the outer loop more one. So for our example inputs it will run like this:
0: 1; 1: 2; 2: 3;
I use it to place the multiplicand multiple times in the current line.
The first line will contain a single 5 (not including the answer for this multiplication) so j is i + 1 which is 1 because during the first iteration from the outer loop i equals 0:
5 = 5
The second line contains 2 5s and i is 1 because we're in the second iteration for the outer loop, so j = i + 1 = 2 which is how many fives we'll place in the string:
5 + 5 = 10
if it's the last iteration of the inner loop instead of adding "5 + " to the resulting string it places "5 = (i + 1) * multiplier" which will be the result for the current line. Then the inner loop ends, the outer loop adds a line break and restarts the process for the next line.

JavaScript - Rand without repetitions with tmp array

Since two days I have a problem with arrays and conditions in JavaScript.
Could you check my code and give me suggestions what should I correct to run this code without infinite loop?
The list of steps (to clarify my problem) - how this code should work:
1. starting the draw
2. Get random quote -> quote[r_quote] where r_quote is random number
3. If the tmp array is empty, add drawn quote into tmp[j]
4. Get next random quote (step 2)
5. If the tmp is not empty
6. Compare all tmp elements with the new, random quote
7. If the new random quote is unique, add it to tmp[j]
I've currently problem with step 7. When this part of code is uncommented, the loop begins to be processed infinity.
var quote = new Array();
quote[0] = 'AAAAAAAAAA';
quote[1] = 'Lorem ipsum.';
quote[2] = 'BBBBBBBBBB';
quote[3] = 'CCCCCCCCCC';
var numberOfQoutes = quote.length;
var r_quote;
var tmp = new Array();
var j = 0;
console.log("start... ");
for (i = 0; i < 3; i++) {
r_quote = Math.floor(numberOfQoutes * Math.random());
console.log('[Step ' + i + '] \t\nquote[' + r_quote + ']' + ' => ' + quote[r_quote]);
if(tmp.length == 0) {
console.log('\ttmp array is empty. You can append ANY quote.');
tmp[j] = quote[r_quote];
console.log('\t\tAppended: ' + tmp[j]);
console.log(j); // show current tmp array position
j++;
} else {
// add just unique qoute
console.log('\ttmp array is not empty.');
console.log('\tChecking if drawn quotation has already been appended.')
for(k = 0; k < tmp.length; k++) {
console.log("\tk=" + k + "\t" + tmp[k] + "\t<< comparing >>\t" + quote[r_quote]);
if(tmp[k] !== quote[r_quote]) { // this if probably doesn't work
console.log("\t\t[OK] You can append quote.");
console.log(j); // show current tmp array position
console.log('\t\tAssign this quote[' + r_quote + '] => ' + quote[r_quote]);
console.log('\t\tInto tmp[' + j + ']');
/* what's wrong here?
tmp[j] = quote[r_quote]; // I want to add random qoute to new position in array
console.log("Appended: " + tmp[j]);
console.log(k);
j++;
*/
}
}
}
}
The problem is that here:
for(k = 0; k < tmp.length; k++) {
you check whether k < tmp.length, and here:
tmp[j] = quote[r_quote];
j++;
you always add another element to the array, so it's length keeps climbing until you run out of memory

Eloquent Javascript: Chessboard

Write a program that creates a string that represents an 8×8 grid, using newline characters to separate lines. At each position of the grid there is either a space or a “#” character. The characters should form a chess board.
My code keeps creating an 8 x 8 structure with all hashes.
Can someone offer some advice to edit my code?
var size = 8;
var str = "";
var altern = false;
var line = 1;
while (line <= size) {
var character = 1;
while (character <= size) {
if (altern) {
if (character % 2 === 0) {
str += "#";
console.log(character);
console.log(str);
} else {
str += " ";
console.log(character);
console.log(str);
}
} else {
if (character % 2 === 0) {
str += " ";
console.log(character);
console.log(str);
} else {
str += "#";
console.log(character);
console.log(str);
}
}
altern = !altern;
character++;
}
str += "\n";
line++;
}
console.log(str);
By using both altern and character % 2 you select the branch with the # every iteration. Use only one of the two.
I couldn't figure out how to answer this myself until I found OP's code. Here is what I found would work:
var size = prompt("What is the size?");
var str = "";
var line = 0;
//Instead of using 1, use 0. It'll make sense in the next comment.
while (line < size) {
var character = 0; // Changed this to 0 as well.
while (character < size) {
if (line % 2 === 0){
/*Instead of using logic negate(altern = !altern), you could use one of the variables
you already have. Changing line = 1 to line = 0, we now can write the conditon above.
Where the first line holds true, because 0 % 2 === 0 is true.*/
if (character % 2 === 0) {
str += " "; // I switched the string values around, to get what is resembled in the book.
console.log(character);
console.log(str);
} else {
str += "#"; // Here
console.log(character);
console.log(str);
}
} else {
if (character % 2 === 0) {
str += "#"; // Here
console.log(character);
console.log(str);
} else {
str += " "; // Here
console.log(character);
console.log(str);
}
}
character++;
}
str += "\n";
line++;
}
alert(str);
//Changed this so the final result is easier to see, rather than in the jumbled mess of the console.
I suspect that you want to toggle altern with each new line, not with each square.
You have a loop inside a loop here. Move your altern toggle code from the inner loop to the outer loop.
while (line <= size) {
var character = 1;
while (character <= size) {
// inner loop code here
character++;
}
// Outer loop end code. HERE is where you toggle altern
str += "\n";
line++;
altern = !altern;
}
Below one works but I replaced spaces with Os (capital o's) and a little change in your code.
var size = 8;
var str = "";
var altern = false;
var line = 1;
while (line <= size) {
var character = 1;
while (character <= size) {
console.log('altern: ' + altern + 'character: ' + character);
if (altern) {
if (character % 2 === 0) {
str += "O";
console.log(character);
console.log(str);
} else {
str += "#";
console.log(character);
console.log(str);
}
} else {
if (character % 2 === 0) {
str += "O";
console.log(character);
console.log(str);
} else {
str += "#";
console.log(character);
console.log(str);
}
}
altern = !altern;
character++;
}
str += "\n";
line++;
}
// console.log(str);
alert(str);
This one works, but not, I suggest you to try to re-write this code in a better way. Hint: pay attention to what #koenpeters said.
Instead of using all those loops you could do this:
var width = 8,
height = 8,
str = new Array(1 + (width * height + height) / 2).join('# ').replace(new RegExp('(.{' + width + '}).', 'g'), '$1\n');
Works as long as width isn't even while at the same time height is odd.
If you just need it for this one specific case you could also get rid of a bit of the overhead and just use this:
var str = new Array(37).join('# ').replace(/(.{8})./g, '$1\n')
Instead of a while loop and over-repetition of your cases based on location (i.e. even vs odd) use two for loops and one case statement for whether a location needs a # vs " ". Store them to a var, then print the var once it is complete.
var board = "";
var countX = 0;
var countY = 0;
var size = 8;
for(var i = 0; i < size; i++) {
for(var j = 0; j < size; j++) {
if((countX + countY) % 2 == 0) {
board += " ";
}
else {
board += "#";
}
countX++;
}
board += "\n";
countY++;
}
console.log(board);
board output:
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
# # # #
i would have tackle this problem by first using a while loop to printing out a line of 8 harsh (########) symbol , then repeat it 8 times vertically using another loop, write a test condition that changes the value of y when the value of both iteration are even numbers.
const size = 8
for(let i = 0; i < size; i++){
let y = " "
let cols = 0;
if(i % 2 == 0){
y = "";
}else{
y = " ";
}
while(cols < size){
if( cols % 2 == 0){
y = y + "#"}
else{
y = y + " "
}
rows++
}
console.log(y)
}
Nested For Loop will work the best for this solution as below ---
//to get the input from the user for any size of the array
var charSize=prompt('Enter Number');
var boardChar = "";
//outer loop
for (let i = 1; i <= charSize; i++) {
//inner loop
for (let j = 1; j <= charSize; j++) {
//Check for even column
let evenCol = (i + j) % 2;
if (evenCol == 0) {
boardChar += " ";
} else {
boardChar += "#";
}
}
boardChar += "\n";
}
console.log(boardChar);
//OUTPUT
[Output Image][1]
The essential thing to realise is that given the N th row, its first square will be black if N is odd, and white otherwise.
Also, if the first square of a given row is black, then for a given column M, the square will be black if M is odd, and white if M is even.
Similarly, if the first square is white, then for a column M, the square will be white if M is odd, and black otherwise.
Hope that helps.
EDIT:
try this if you’re a fan of unreadable code:
for i in range(8):
s = ''
for j in range(8):
if (i - j%2) % 2 == 0:
s = s + "#"
else: s = s + 'O'
print s
I also learn JavaScript currently. I was stuck on that for one day. The only thing, that I realize, that if you want to do something useful in JavaScript use loops.
I don't have an idea about complicated coding, but loops could easily do things, that seems at first to be complicated.
Here is my version:
let b = "" //**just create an empty string, because if you won't do that, loop will print out symbols, numbers etc in a single column, but if you use empty string you can in future write symbols inside that string, which allows you to expand string horisontally
let size = 8 //**since loops start at 0 to infinity, you must take it into account,
for (let i = 0; i < size; i++) //**create first loop --> (; ; ). As you can see inside body of loop (the expression, that will be executed until loop is valid) I have just b = b + "#", which means, that my first "for" loop will do looping :) 8 times and will store inside "b" variable THE LAST VALUE (it will be ########), you can check this out in a single sheet (and you will see, that this looping is still going vertically, but the point is that it stores the LAST VALUE)
{ b = b + "#"} //**that is the body of first loop which is described clearly above
for (let a = 0; a < size; a++) //**inside second loop, we create the same routine, and proceed inside that loop with value of "b" from first loop. Notice, that first loop is enclosed {}, so it act independantly.
{
if (a % 2 == 0) //**just condition, which allows us to distribute different strings (rows) of code (I hope you understand what is inside parenthesis
{console.log (" " + b)} //**Since we want to see our chessboard we should print this out onto screen, for that we use "console.log" but again, notice, that here WE DON'T change value of variable "b", we just operate with it, but it will stay the same "########"
else{
console.log (b)} //** And if "if" fails, we will proceed with "########" value, which is NEW origin of "b" variable
}

Javascript While loop integers

I have to create a while loop displaying the integers from 1-20 but only 5 integers per line.
I can't get the 5 integers per line part. What is the best way to do that?
Check if it's the next item after a multiple of 5 and if the current item is not the first item. If it is, also print out a newline. For example:
for(var i = 1; i <= 20; i++) {
print(i); // Or however you're outputting it
if(i % 5 === 1 && i > 1) {
print('\n');
}
}
Here's a solution that builds a string and displays an alert box with the result.
var i = 0, result = "";
while (i++ < 20) {
result += i + " ";
// check to see if we're at 5/10/15/20 to add a new-line
if (i % 5 === 0) {
result += "\n";
}
}
alert(result);
jsFiddle to test: http://jsfiddle.net/willslab/KUVkX/3/
You can do...
if ( ! (i % 5)) {
// Create new line.
}
jsFiddle.
See no while loops in previous answers =)
function generateLine(start, nElements, separator) {
var i = start;
var range = [];
while (range.length < nElements) range.push(i++);
return range.join(separator) + '\n';
}
function generate(start, end, elementsInLine, inlineSeparator) {
var lines = [];
while (start < end) {
lines.push( generateLine(start, elementsInLine, inlineSeparator));
start += elementsInLine;
}
return lines.join('');
}
console.log( generate(1, 20, 5, ' ') );

Categories