Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 months ago.
Improve this question
I'm trying to print out the multiplication table using js. Is there a cleaner way to do this than with nested for loops? I was thinking of reduce as an alternative. Any onther ideas out there? ;)
let table = () => {
let x, y, sum;
let table = '';
for (y = 10; y <= 20; y++) {
for (x = 10; x <= 20; x++) {
sum = x * y;
table += `|${sum} `;
}
table += '|\n';
}
result.innerText = table;
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Task 4</title>
</head>
<body onload="table()">
<h2>Multiplication table</h2>
<div id="result"></div>
</body>
</html>
Using Array#from to create a 2D array and Array#map and Array.join to turn into a table formatted as a delimited string makes it easier to read than using Array#reduce.
What makes this easier to read and more flexible is that there is one step to generate your data model (2d array) and another to convert it to a string. Therefore, if you wanted to turn into an HTML table, it'd be really easy.
const table = Array.from(
{length: 11},
(e, x) => Array.from(
{length: 11},
(e, y) => (x + 10) * (y + 10)
)
);
const str = table.map((row) => `| ${row.join(" | ")} |`).join("\n");
console.log({
table
});
result.innerText = str;
const html = `
<table><tbody>
${table.map(row =>
`<tr>${row.map(el =>
`<td>${el}</td>`).join("")
}</tr>`).join("")
}
</tbody></table>`;
console.log({
html
});
htmlTable.innerHTML = html;
table,
td {
border: 1px solid black;
}
<div id="result"></div>
<div id="htmlTable"></div>
Yes it is possible. Since you have a nested for loop, you need two reduces: a reduce per row and a reduce for the entire table :
range.map(x =>
range.map(y => x * y).reduce((row, sum) => row + `|${sum} `), '')
.reduce((table, row) => table + row + '|\n', '');
That being said, in your case you'd probably want to create an HTML table.
Snippet
let table = () => {
const range = Array.from({length: 11}, (x, i) => i + 10);
result.innerText = range.map(x =>
range.map(y => x * y).reduce((row, sum) => row + `|${sum} `), '')
.reduce((table, row) => table + row + '|\n', '');
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Task 4</title>
</head>
<body onload="table()">
<h2>Multiplication table</h2>
<div id="result"></div>
</body>
</html>
Related
I have a script like this
let x;
let y;
let z;
let obliczone;
document.getElementById("srednia").onclick = function() {
x = document.getElementById("grade1").value;
y = document.getElementById("grade2").value;
z = document.getElementById("grade3").value;
x = Number(x);
y = Number(y);
z = Number(z);
obliczone = Number(obliczone);
obliczone = (x + y + z) / 3;
console.log(obliczone);
document.getElementById("wynik").innerHTML = "Twoja średnia to " + obliczone;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="main.css">
<title>Document</title>
</head>
<body>
<label>Ocena 1</label> <input type="text" id="grade1"><br>
<label>Ocena 2</label> <input type="text" id="grade2"><br>
<label>Ocena 3</label> <input type="text" id="grade3"><br>
<label>Oblicz: </label> <button id="srednia">Średnia</button>
<p id="wynik"></p>
<script src="index.js"></script>
</body>
</html>
and if user type in a number with "+" like 2+ I want i to give me 2.5 value and if the input is higher than 6 to break the function. It meant to calculate arithmetic mean of 3 digits and as I wrote earlier it should change ex. 1+ to 1.5
By default when the JavaScript interpreter tries to cast the string to a number and this string contains a symbol it results in a NaN (Not a Number). You can do what you want by replacing the '+' symbol with '.5'.
The new code:
let x;
let y;
let z;
let obliczone;
document.getElementById("srednia").onclick = function () {
x = document.getElementById("grade1").value;
y = document.getElementById("grade2").value;
z = document.getElementById("grade3").value;
const doesXEndsWithPlus = x.endsWith('+')
const doesYEndsWithPlus = y.endsWith('+')
const doesZEndsWithPlus = z.endsWith('+')
if (doesXEndsWithPlus) x = x.replace('+', '.5')
if (doesYEndsWithPlus) y = y.replace('+', '.5')
if (doesZEndsWithPlus) z = z.replace('+', '.5')
x = Number(x);
y = Number(y);
z = Number(z);
obliczone = Number(obliczone);
obliczone = (x + y + z) / 3;
console.log(obliczone);
document.getElementById("wynik").innerHTML = "Twoja średnia to " + obliczone;
}
This is one way you can do it however if you end up putting more than 3 inputs it can start getting repetitive.
document.getElementById("srednia").onclick = function(){
let obliczone;
let x = document.getElementById("grade1").value;
let y = document.getElementById("grade2").value;
let z = document.getElementById("grade3").value;
if (x.includes('+')) {
x = parseFloat(x.split("+")[0] + ".5")
}
if (y.includes('+')) {
y = parseFloat(y.split("+")[0] + ".5")
}
if (z.includes('+')) {
z = parseFloat(z.split("+")[0] + ".5")
}
obliczone = (x+y+z) / 3;
console.log(obliczone);
document.getElementById("wynik").innerHTML = "Twoja średnia to " + obliczone;
}
One solution to make it cleaner and more dynamic is to create a helper function formatNumInput(input):
function formatNumInput(input) {
let newNum;
if (input.includes('+')) {
newNum = parseFloat(input.split("+")[0] + ".5")
} else {
newNum = parseFloat(input)
}
return newNum
}
document.getElementById("srednia").onclick = function(){
let obliczone;
let x = document.getElementById("grade1").value;
let y = document.getElementById("grade2").value;
let z = document.getElementById("grade3").value;
x = formatNumInput(x)
y = formatNumInput(y)
z = formatNumInput(z)
obliczone = (x+y+z) / 3;
console.log(obliczone);
document.getElementById("wynik").innerHTML = "Twoja średnia to " + obliczone;
}
I would like to propose you something a little bit different that could to inspired you and where are not you are not limited only to 3 values of ratings:
//here I define some globals variables
let evaluation = document.getElementById('eval');
let evaluations = [];
let showEval = document.getElementById("evaluation");
let addEval = document.getElementById("addEval");
let average = 0
function showEvals (){
for (let i = 0; i < evaluations.length; i++) {
showEval.innerHTML += `<span>${evaluations[i]}</span>, `
};
};// this is a function to show ratings
function countAverage () {
let sum = 0
for (let i = 0; i < evaluations.length; i++) {
const rating = parseFloat(evaluations[i],10)//here I convert a string go float (Numners() create variable type object not type number
sum += rating
average = (sum/evaluations.length).toFixed(2)// I limited my float to 2 digits
};
document.getElementById("result").innerHTML = "Twoja średnia to " + average
} // this function counts and shows average
addEval.onclick = function(){
evaluations.push(evaluation.value)
showEval.innerHTML = [];
showEvals();
countAverage();
};// here new rangs is pushed to the array of evaluations and it calls ather functions
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="script.js" defer></script>
</head>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="script.js" defer></script>
</head>
<body>
<label for="eval">Dodaj ocene:</label>
<select name="evals" id="eval">
<option value="1">1</option>
<option value="1.5">1+</option>
<option value="2">2</option>
<option value="2.5">2+</option>
<option value="3">3</option>
<option value="3.5">3+</option>
<option value="4">4</option>
<option value="4.5">4+</option>
<option value="5">5</option>
<option value="5.5">5+</option>
<option value="6">6</option>
</select>
</select>
<button id="addEval">Dodaj ocene</button>
<h2>Twoje oceny to:</h2>
<div id="evaluation"></div>
<p id="result"></p>
</body>
</html>
I'm learning JS and I coded an "arabic to roman numbers" converter. Everything is working fine when I console log. But the next step is to display these informations in html like following :
Arabic number :
Roman number :
Here's my code so far :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Converter</title>
</head>
<body>
<p>Arabic number :</p>
<p id="numberInput"></p>
<p>Roman number :</p>
<p id="romainInput"></p>
<script src="./index.js"></script>
</body>
</html>
And the Js part :
let romanInput = document.getElementById("romanIput");
let arabicInput = document.getElementById("numberInput");
function convertToRoman(num) {
const romanToNum = {
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
let roman = "";
for (let key in romanToNum) {
while (num >= romanToNum[key]) {
roman += key;
num -= romanToNum[key];
}
}
return roman;
}
console.log(convertToRoman(2));
I just need to choose a random number in the console between 1 and 10 and to display it. I tried different things with "romanInput.innerHtml = roman.value" and things like that but nothing working so far. Any ideas ?
Thanks in advance...
if you want to generate random number and pass it to your function you can write a function like this:
function getRandomNumberBetween(min,max){
return Math.floor(Math.random()*(max-min+1)+min);
}
var rndNum = getRandomNumberBetween(1,10);
console.log(convertToRoman(rndNum));
You had miss spelled innerHTML as innerHtml. That's why it won't work.
let romanInput = document.getElementById("romanIput");
let arabicInput = document.getElementById("numberInput");
function convertToRoman(num) {
const romanToNum = {
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
let roman = "";
for (let key in romanToNum) {
while (num >= romanToNum[key]) {
roman += key;
num -= romanToNum[key];
}
}
return roman;
}
arabicInput.innerHTML = convertToRoman(2)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Converter</title>
</head>
<body>
<p>Arabic number :</p>
<p id="numberInput"></p>
<p>Roman number :</p>
<p id="romainInput"></p>
</body>
</html>
You are nearly there. Just add an eventlistener to your input field and actual make it a html input field.
After this you can listen to events and read the value which is in the input.
I used the keyup event to update the value immediately.
let romanOutput = document.getElementById("romanOutput");
let arabicInput = document.getElementById("numberInput");
arabicInput.addEventListener("keyup", e => convertToRoman(Number(e.target.value)))
function convertToRoman(num) {
const romanToNum = {
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
let roman = "";
for (let key in romanToNum) {
while (num >= romanToNum[key]) {
roman += key;
num -= romanToNum[key];
}
}
romanOutput.innerHTML = roman;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Converter</title>
</head>
<body>
<p>Arabic number :</p>
<input id="numberInput" />
<p>Roman number :</p>
<p id="romanOutput"></p>
</body>
</html>
let myLeads = [];
const inputEl = document.getElementById("input-el");
const inputBtn = document.getElementById("input-btn");
const ulEl = document.getElementById("ul-el");
inputBtn.addEventListener("click", function(){
myLeads.push(inputEl.value);
console.log(myLeads)
})
let arr = [2, 3, "fadf"]
/*arr[] elements are rendered correctly in HTML list. But myLeads[] elements are not rendered in HTML list, as they are printed correctly in console.*/
for(let i = 0; i < myLeads.length; i++){
ulEl.innerHTML += "<li>" + myLeads[i] + "</li>"
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>save leads</title>
<link rel="stylesheet" href="/index.css">
</head>
<body>
<input type="text" id="input-el">
<button id="input-btn">Save tabs</button>
<ul id="ul-el"></ul>
<script src="/index.js"></script>
</body>
</html>
Put the loop in a function and call it. Also make sure to reset the ul to be empty
let myLeads = [];
const inputEl = document.getElementById("input-el");
const inputBtn = document.getElementById("input-btn");
const ulEl = document.getElementById("ul-el");
inputBtn.addEventListener("click", function(){
myLeads.push(inputEl.value);
updateList();
})
let arr = [2, 3, "fadf"]
/*arr[] elements are rendered correctly in HTML list. But myLeads[] elements are not rendered in HTML list, as they are printed correctly in console.*/
function updateList(){
ulEl.innerHTML = "";
for(let i = 0; i < myLeads.length; i++){
ulEl.innerHTML += "<li>" + myLeads[i] + "</li>"
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=\, initial-scale=1.0">
<title>save leads</title>
<link rel="stylesheet" href="/index.css">
</head>
<body>
<input type="text" id="input-el">
<button id="input-btn">Save tabs</button>
<ul id="ul-el"></ul>
<script src="/index.js"></script>
</body>
</html>
You are not updating the HTML element anywhere when the click event is being fired. That means your list is only populated by the initial elements of myLeads when the page is refreshed and then never again.
Move the cycle for generating li elements into a function, for example
function updateList(arr){
ulEl.innerHTML = "";
for(let i = 0; i < arr.length; i++){
ulEl.innerHTML += "<li>" + myLeads[i] + "</li>"
}
}
and then call it inside the event handler
inputBtn.addEventListener("click", function(){
myLeads.push(inputEl.value);
console.log(myLeads)
updateList(myLeads);
})
Below is the function for insertion sort. I want that user should give the input from html form as an array elements instead of hard coding the elements of array. I have tried several techniques but in vain.
function insertionSort (inputArr) {
let length = inputArr.length;
for (let i = 1; i < length; i++) {
let key = inputArr[i];
let j = i - 1;
while (j >= 0 && inputArr[j] > key) {
inputArr[j + 1] = inputArr[j];
j = j - 1;
}
inputArr[j + 1] = key;
}
return inputArr;
};
let inputArr = [2,4,5,36,2,6,26,8,3,7]; // I want here user input which comes from html form instead of hard-coding elements of array like this
insertionSort(inputArr);
console.log(inputArr);
// Event listner
function getData() {
let userData = document.getElementById('data').value;
return userData;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-
scale=1.0">
<title>Insertion Sort In JavaScript</title>
</head>
<body>
<h1>Insertion Sort in JavaScript</h1>
<form action="#">
<label for="data">Write Random Numbers</label>
<input type="text" name="data" id="data">
<button onclick="getData()">Submit</button>
</form>
<div id="printData"></div>
<script src="insertionsort.js"></script>
I am trying to make a function in JAVASCRIPT that calculates the HCF, in the VS CODE (MY CODE EDITOR) console it's showing the correct value, but I am trying to display the result on the page and it's not appearing and in the browser's console its showing maximum call stack exceeded.
The result of the if statement appears but when the if statement is false, the result of the else statement does not appear.
Here is my code:
function HCF(a, b) {
var answer = document.getElementById('answer');
let value1 = document.getElementById('value1').value;
let value2 = document.getElementById('value2').value;
a = value1;
b = value2;
var ans = 0;
if (a % b == 0) {
return answer.innerHTML = `HCF: ${b}`;
}
var remainder = a % b;
ans += HCF(b, remainder);
answer.innerHTML = `HCF: ${ans}`;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maths Problem</title>
</head>
<body>
<h1>Value 1: </h1><input type="text" id="value1">
<h1>Value 2: </h1><input type="text" id="value2"><br><br>
<button type="submit" id="submit" onclick="HCF()">Get answer</button>
<h1 id="answer">HCF:</h1>
</body>
</html>
You need to separate out the code that calculates the HCF and which gets and displays values.
function HCF(a, b) {
if (a % b == 0) {
return b;
}
var remainder = a % b;
return HCF(b, remainder);
}
function getHCF() {
const a = document.getElementById('value1').value;
const b = document.getElementById('value2').value;
const answer = HCF(a, b);
document.getElementById('answer').innerHTML = `HCF: ${answer}`;
}
<h1>Value 1: </h1><input type="text" id="value1">
<h1>Value 2: </h1><input type="text" id="value2"><br><br>
<button type="submit" id="submit" onclick="getHCF()">Get answer</button>
<h1 id="answer">HCF:</h1>
</body>
I've separated your function into two functions. One function calls the other which is recursive and which returns the answer to the first function which then displays the results to the page.
function HCF() {
var answer = document.getElementById('answer');
let value1 = document.getElementById('value1').value;
let value2 = document.getElementById('value2').value;
answer.innerHTML = HCFHelper(value1, value2);
}
function HCFHelper(a, b) {
if (a % b == 0) {
return b;
}
return HCFHelper(b, a % b);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Maths Problem</title>
</head>
<body>
<h1>Value 1: </h1><input type="text" id="value1">
<h1>Value 2: </h1><input type="text" id="value2"><br><br>
<button type="submit" id="submit" onclick="HCF()">Get answer</button>
<h1 id="answer">HCF:</h1>
</body>
</html>