Making the full sentence bold, even after added 'and' in javascript - javascript

I have a question regarding the message I'd like to display based on some values.
I have 4 categories that have some values and I need to display the message if they show high risk. The message is based on the number of risks which can be from 1 to 4 factors hence two messages where I'm using "factor IS" and "factors ARE".
My problem is I cannot make those factors bold after I add 'and' in my else statement. The beginning of the sentence is bold but not the last risk which comes after 'and'.
I'm adding 'and' before the last item of my array as I don't want comma (I found the code on: Array to Comma separated string and for last tag use the 'and' instead of comma in jquery).
Thanks for your help and suggestions!
function displayMessage() {
var getRiskFactors = calculateRisk();
var getRiskFactorsLength = getRiskFactors.length;
for (var i=0; i < getRiskFactorsLength; i++ ) {
if(getRiskFactorsLength === 1) {
var message = "Your main risk factor is your <b>" + getRiskFactors[0] + "</b>";
} else {
//this joins items from the array with comma if there's
//more than one factor.
//it also adds "AND" before the last item in the array
// instead of comma
var message = "Your main risk factors are your " + [getRiskFactors.slice(0, -1).join(", "), getRiskFactors.slice(-1)[0]].join(getRiskFactors.length < 2 ? "" : " and " + "</b>");
}
}
return message;
}

You are not starting and closing the bold tag
let getRiskFactors = [ 1,2,3,4 ];
var output = "Your main risk factors are your " + [ "<b>" + getRiskFactors.slice(0, -1).join(", "), getRiskFactors.slice(-1)[0]].join(getRiskFactors.length < 2 ? "" : "</b> and <b>") + "</b>";
document.body.innerHTML = output;
console.log(output);

You've misplaced your start <b> tag in the else clause and you are always adding a closing </b> tag after each and.
Just enclose the whole thing like this:
else {
var message = "Your main risk factors are your <b>" + [getRiskFactors.slice(0, -1).join(", "), getRiskFactors.slice(-1)[0]].join(getRiskFactors.length < 2 ? "" : " and ") + "</b>";
}

There is a balance between writing concise code and debuggable/readable code. This is a good illustration of trying to be too clever. I tried to make your code a little more readable.
In my experience I have found errors arise when using concatenation of strings and the ?: operator on the same line. Try the following code and edit as necessary.
var getRiskFactors = calculateRisk();
var getRiskFactorsLength = getRiskFactors.length;
for (var i=0; i < getRiskFactorsLength; i++ ) {
if(getRiskFactorsLength === 1) {
var message = "Your main risk factor is your <b>";
message+= getRiskFactors[0] + "</b>";
} else {
//this joins items from the array with comma if there's
//more than one factor.
//it also adds "AND" before the last item in the array
// instead of comma
var message = "Your main risk factors are your ";
var arraypart1 = getRiskFactors.slice(0, -1).join(", ");
var arraypart2 = getRiskFactors.slice(-1)[0];
var computation = getRiskFactors.length < 2 ? "" : " and ";
var joinedarray = [];
joinedarray.push(arraypart1);
joinedarray.push(arraypart2);
message += joinedarray.join(compution) + "</b>";
}
}
return message;

Related

how do I get charAt() to check every first letter after splitting a string?

How do I get charAt() to display the letters of all the splitted values at index=0? I don't know what to write before the .charAt() in order to arrange to give me the letters of all the splitted values at index=0, it gives me one value though:
<button onclick="occurence('The quick brown fox jumps over the lazy
dog')">Go</button>
<p id="demo"></p>
<script>
function occurence(str) {
//conversion to string to make get the value of every single letter
var spl = str.split("");
//loop to subtract from spl.length to get value for chartAt
for (i = 0; i < spl.length; i++) {
}
document.getElementById("demo").innerHTML = spl[i - spl.length].charAt(0) +
"<br>";
}
</script>
This is the working version of your code:
function occurence(str) {
//conversion to string to make get the value of every single letter
var spl = str.split(" ");
//loop to subtract from spl.length to get value for chartAt
var firstLetters = []
for (i = 0; i < spl.length; i++) {
firstLetters.push(spl[i].charAt(0));
}
document.getElementById("demo").innerHTML = firstLetters.join("<br>");
}
<button onclick="occurence('The quick brown fox jumps over the lazy dog')">Go</button>
<p id="demo"></p>
First of all The quick brown fox jumps over the lazy dog text from your question was giving me some error. There was probably an encoding issue so I rewrite it by hand.
You should split your string with str.split(" ") not str.split("").
You need to define an array like this var firstLetters = [] to use it as a stack inside to for loop.
You get the first letter of a word by spl[i].charAt(0) and you need to push this letter with firstLetters.push(spl[i].charAt(0)) inside the for loop.
Lastly you join firstLetters stack and display inside the demo tag with: document.getElementById("demo").innerHTML = firstLetters.join("") + "<br>"
I apologize for not explaining my question properly. I was trying to make a program that takes input in two textboxes in one the user enters text in which they would want to know how many of the specified characters entered in the second textbox are found in the text entered in the first textbox. A lot of you told me to split with " " not "" but " " would not have given me the charAt(0) of ever single character. I have built the program and used mertyildiran's code to get the charAt(0) for every single letter.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
enter text:
<input id="enteredText" type="text">
enter text to be checked:
<input id="toBeChecked" type="text">
<button onclick="occurence()">Go</button>
<p id="demo"></p>
<script>
function occurence() {
//value of entered text to be checked
var inpTextToCheck = document.getElementById("toBeChecked").value
//value of entered text
var inpText = document.getElementById("enteredText").value
//conversion to string to make get the value of every single letter
var spl = inpText.split("");
//loop to get all letters at index = 0(all letters actually, since they are
now an array)
var allLetters = []
for (i = 0; i < spl.length; i++) {
allLetters.push(spl[i].charAt(0));
}
var inpLetters = allLetters.join();
//conversion of letter or word entered by user to RegExp so it can be used as
a variable in match()
var re = new RegExp(inpTextToCheck, 'gi');
//number of times the text to be checked is found in the entered text
numOfOccurences = (inpText.match(re) || []).length
// if the text to be checked is a number and is found once in the entered
text
if (numOfOccurences == 1 && inpTextToCheck >= 0 || inpTextToCheck <= 0) {
document.getElementById("demo").innerHTML = "The number " + inpTextToCheck
+ " was found once in the entered text"
}
//if the text to be checked is a number and is found more than once in the
entered text
else if (inpTextToCheck >= 0 || inpTextToCheck <= 0) {
document.getElementById("demo").innerHTML = "The number " + inpTextToCheck +
" was found "
+ numOfOccurences + " times in the entered text"
}
//if the text to be checked is a letter and was found once in the entered text
else if (inpTextToCheck.length == 1 && numOfOccurences == 1) {
document.getElementById("demo").innerHTML = "The letter " + '"' +
inpTextToCheck + '"' + " was found once in the entered text"
}
//if the text to be checked is a letter and was found more than once in the
entered text
else if (inpTextToCheck.length == 1 && numOfOccurences > 1) {
document.getElementById("demo").innerHTML = "The letter " + '"' +
inpTextToCheck + '"' + " was found " + numOfOccurences+ " times in the entered
text"
}
//if the text to be checked is found once and is a word or letter combination
else if (inpTextToCheck.length > 1 && numOfOccurences == 1) {
document.getElementById("demo").innerHTML = "The word or letter combination "
+ '"' + inpTextToCheck + '"' + " was found once in the entered text"
}
//if the text to be checked is found more than once and is a word or letter
combination
else if (inpTextToCheck.length > 1 && numOfOccurences > 1) {
document.getElementById("demo").innerHTML = "The word or letter combination "
+ '"' + inpTextToCheck + '"' + " was found " + numOfOccurences + " times in
the entered text"
}
if (numOfOccurences == 0) {
document.getElementById("demo").innerHTML = '"' + inpTextToCheck + '"' + " was
not found in the entered text";
}
}
</script>
</body>
</html>
You need to do this:
1. Split the passed argument with " " NOT ""
2. Collect the value of each word's first letter in the string in the loop and then update html of demo outside the loop.
3. To get the first letter of the split string do spl[i].charAt(0)
function occurence(str) {
//conversion to string to make get the value of every single letter
var spl = str.split(" ");
var str ="";
//loop to subtract from spl.length to get value for chartAt
for (i = 0; i < spl.length; i++) {
str += spl[i].charAt(0) + "<br>";
}
document.getElementById("demo").innerHTML = str;
}
<button onclick="occurence('The quick brown fox jumps over the lazy dog')">Go</button>
<p id="demo"></p>
You can use String.prototype.match() with RegExp /\b\w/g to match word boundary followed by one word character, chain Array.prototype.join() with parameter "<br>" to resulting array.
<button onclick="occurrence('The quick brown fox jumps over the lazy dog')">Go</button>
<p id="demo"></p>
<script>
function occurrence(str) {
document.getElementById("demo").innerHTML = str.match(/\b\w/g).join("<br>")
}
</script>
If I get you correctly, you want to display the letters at index 0 of the individual words of the string str.
You should split on " " not "", and the innerHTML of #demo should be updated in the loop not outside.
I have modified your code to achieve what I think you're talking about.
function occurence(str) {
//conversion to string to make get the value of every single letter
var spl = str.split(" "); // split on " " not ""
//loop to subtract from spl.length to get value for chartAt
for (i = 0; i < spl.length; i++) {
// innerHTML of #demo should be updated in the loop not outside
document.getElementById("demo").innerHTML += spl[i].charAt(0) + "<br>";
}
}
<button onclick="occurence('The quick brown fox jumps over the lazy dog')">Go</button>
<p id="demo"></p>

How can I prepend characters to a string using loops?

I have an input field that expects a 10 digit number. If the user enters and submits a number less than 10 digits, the function would simply add a "0" until the inputed value is 10 digits in length.
I haven't really used, or understand how recursive functions really work, but I'm basically looking at an efficient way of doing this. One minor issue I'm having is figuring out how to prepend the "0"s at the beginning of the string rather than appended to the end.
My thinking:
function lengthCheck(sQuery) {
for (var i = 0; i < sQuery.length; i++) {
if (sQuery.length !== 10) {
sQuery += "0";
//I'd like to add the 0s to the beggining of the sQuery string.
console.log(sQuery);
lengthCheck(sQuery);
} else return sQuery
}
}
Change:
sQuery += "0"; // added at end of string
to:
sQuery = "0" + sQuery; // added at start of string
To remove the for loop/recursion, you could slice out the desired length in one step:
function padZeros(sQuery) {
// the max amount of zeros you want to lead with
const maxLengthZeros = "0000000000";
// takes the 10 rightmost characters and outputs them in a new string
return (maxLengthZeros + sQuery).slice(-10);
}
Simple generic function using ES6 repeat:
// edge case constraints not implemented for brevity
function padZeros(sQuery = "", maxPadding = 10, outputLength = 10) {
// the max amount of zeros you want to lead with
const maxLengthZeros = "0".repeat(maxPadding);
// returns the "outputLength" rightmost characters
return (maxLengthZeros + sQuery).slice(-outputLength);
}
console.log('padZeros: ' + padZeros("1234567890"));
console.log('padZeros: ' + padZeros("123"));
console.log('padZeros: ' + padZeros(""));
Alternate version that doesn't affect strings over your set limit:
function padZerosIfShort(inputString = "", paddedOutputLength = 10) {
let inputLen = inputString.length;
// only padded if under set length, otherwise returned untouched
return (paddedOutputLength > inputLen)
? "0".repeat(paddedOutputLength - inputLen) + inputString
: inputString;
}
console.log('padZerosIfShort: ' + padZerosIfShort("1234567890", 5));
console.log('padZerosIfShort: ' + padZerosIfShort("123", 5));
console.log('padZerosIfShort: ' + padZerosIfShort("", 5));
It will ultimately depend on your needs how you want to implement this behavior.
The += operator adds things to the end of strings similar to:
sQuery=sQuery+"0"
You can add characters to the front of a string like this
sQuery="0"+sQuery
I also found something interesting here. it works like this:
("00000" + sQuery).slice(-5)
You would add zeros to the front then slice off everything except the last 5. so to get 10 characters you would use:
("0000000000" + n).slice(-10)
You don't need recursion to solve this, just a simple for loop should do the trick. Try this:
function lengthCheck (sQuery) {
for (var i = sQuery.length; i<10; i++) {
sQuery = "0" + sQuery;
}
return sQuery;
}
You're looking to pad the string with zeroes. This is an example I've used before from here and will shorten your code a little bit:
function lengthCheck (sQuery) {
while (sQuery.length < 10)
sQuery = 0 + sQuery;
return sQuery;
}
I believe this has already been answered here (or similar enough to provide you the solution): How to output integers with leading zeros in JavaScript

js last array item is undefined

I am trying to make a hangman game and in the beginning the game asks the user for the word. Once it has the word it fills the word letters one by one in an array using a for loop. Unfortunately the last array element is always undefined for some reason.
Code(JS):
for(i=0;i<word.length;i++)
{
if(i == word.length - 1)
{
wordLettersLeft = word.length;
$("#cEText").removeAttr("style");
$(".characterEnter").removeAttr("style");
$("#gBtn").text("Lopeta");
gameStarted = true;
pcArrayLength = pcArray.length;
lives = 4;
alert("Peli alkaa! Sinulla on " + lives + " yritystä jäljellä.");
alert("Vihje: " + hint);
alert("Sinulla on vielä " + wordLettersLeft + " arvattavaa kirjainta jäljellä.");
}
else
{
pcArray.push(word[i]);
}
}
This has a very simple reason: you are not adding the last letter to your pcArray. Let's assume our word is 'bird' (because bird is a word). Your code would go through the letters b, i and r and push those to your array, so far so good. But when it hits the d, it is at position word.length-1 - because the array length starts at 1 but the index starts at 0. Your if statement prevents it from pushing the last letter to the word. There are two solutions:
First, you could simply remove the else statement:
for(i=0;i<word.length;i++){
if(i == word.length - 1){
wordLettersLeft = word.length;
$("#cEText").removeAttr("style");
$(".characterEnter").removeAttr("style");
$("#gBtn").text("Lopeta");
gameStarted = true;
pcArrayLength = pcArray.length;
lives = 4;
alert("Peli alkaa! Sinulla on " + lives + " yritystä jäljellä.");
alert("Vihje: " + hint);
alert("Sinulla on vielä " + wordLettersLeft + " arvattavaa kirjainta jäljellä.");
}
pcArray.push(word[i]);
}
That will push every letter every time! However, There is a more efficient way:
for(i=0;i<word.length;i++)
pcArray.push(word[i]);
wordLettersLeft = word.length;
$("#cEText").removeAttr("style");
$(".characterEnter").removeAttr("style");
$("#gBtn").text("Lopeta");
gameStarted = true;
pcArrayLength = pcArray.length;
lives = 4;
alert("Peli alkaa! Sinulla on " + lives + " yritystä jäljellä.");
alert("Vihje: " + hint);
alert("Sinulla on vielä " + wordLettersLeft + " arvattavaa kirjainta jäljellä.");
This way you will only execute your initial code once instead of checking the if every time. You know your loop will only run for as long as there are letters, so why even bother with the if?
As #Shilly mentions in the comments, you can forego the for loop altogether by doing this:
pcArray = word.split('');
Let's say someone's inputing the word "Test". For i === 3 which is the last iteration, you enter the if clause and you're missing out on the else clause, which is where you're doing:
pcArray.push(word[i]);
What you want is to do this anyway, regardless of whether you're in the if or the else, so you can just drop the else clause and do it anyway.
The last step of your loop does not execute pcArray.push(word[i]);. So obvioulsy, the last value is missing.
But if you want to convert a string into an array, just do this :
var pcArray = word.split('');

why is this while loop causing an infinite loop?

For some reason I'm having difficulty getting this while loop to work. It keeps crashing my browser whenever I try to test it out, and in the one case that I was able to see the results of the loop in the console, all I saw was NaN printed several times. Is there something I've forgotten in my code?
<div id="output"></div>
<script>
var starting = prompt("What is your starting balance?");
var target = prompt("What is your target balance?");
var interest = prompt("What is your interest rate?");
var periods = 0;
var current = starting;
var greaterThan = false;
while (greaterThan === false) {
if (current < target) {
current = current + (current * interest);
periods++;
} else {
greaterThan = true;
alert("it took " + periods + " periods to make your starting balance greater than your target balance.");
document.querySelector('#output').textContent = "to grow an initial investment of " + starting + " to " + target + " at a " + interest + " interest rate will require " + periods + " investment periods.";
}
}
</script>
The one problem I could see is, all your input values are string, not numbers so they are doing string comparison not numeric
var starting = +prompt("What is your starting balance?") ||0;
var target = +prompt("What is your target balance?")||0;
var interest = +prompt("What is your interest rate?")||1;
The + in front of prompt() is the unary plus operator
You are forgetting to convert the result from prompt from a string into a number.
var starting = parseFloat(prompt("What is your starting balance?"));
Do the same thing to the other numbers that are input by the user from the prompt.
First you need to convert your input into an integer value. The input from the prompt is a string. even if you enter 1 or 10 or any number. You can use parseInt() for that. and because you are asking for interest rate, i think any user would enter something like 2. 5, or 10 as a percentile. not 0.1, or 0.05. Even if he does, the parseInt() function can't get it right because 0.05 is not an integer value. You can use parseFloat for that. so i suggest you look at my implementation of your code below. also, i have omitted the if else statements because they weren't necessary and would only make the code more complex.
<div id="output"></div>
<script type="text/javascript">
var starting = parseInt(prompt("What is your starting balance?"));
var target = parseInt(prompt("What is your target balance?"));
var interest = parseInt(prompt("What is your interest rate?"));
var periods = 0;
var intrate = interest/100;
var current = starting;
while (current< target) {
current += (current*intrate);
periods += 1;
}
alert("it took " + periods + " periods to make your starting balance greater than your target balance.");
document.querySelector('#output').textContent = "to grow an initial investment of " + starting + " to " + target + " at a " + interest + " interest rate will require " + periods + " investment periods.";
</script>

How to add newline after a repeating pattern

Assume that there is a string like this:
var content = "1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20";
I want to add <br /> after every 5 dots.
So, the result should be:
1.2.3.4.5.<br />
6.7.8.9.10.<br />
11.12.13.14.15.<br />
16.17.18.19.20.<br />
I want to do this without a for loop. Is it possible with just regex?
i'm doing this with this code;
regenerate:function(content,call){
var data2;
var brbr = content.replace(/[\u0250-\ue007]/g, '').match(/(\r\n)/g);
if (brbr !== "") {
data2 = content.replace(/[\u0250-\ue007]/g, '').replace(/(\r\n)/gm, "<br><br>");
} else {
data2 = content.replace(/[\u0250-\ue007]/g, '');
}
var dataArr = data2.split(".");
for (var y = 10; y < dataArr.length - 10; y += 10) {
var dataArrSpecific1 = dataArr[y] + ".";
var dataArrSpecific2 = dataArr[y] + ".<br>";
var dataArrSpecificBosluk = dataArr[y + 1];
var data3 = data2.replace(new RegExp(dataArrSpecific1.replace(/[\u0250-\ue007]/g, ''), "g"), "" + dataArrSpecific2.replace(/[\u0250-\ue007]/g, '') + "");
data3 = data3.replace(new RegExp(dataArrSpecificBosluk.replace(/[\u0250-\ue007]/g, ''), "g"), " " + dataArrSpecificBosluk.replace(/[\u0250-\ue007]/g, '') + "");
data2 = data3;
}
call(data2.replace(/[\u0250-\ue007]/g, ''));
}
Actually , i want to refactoring this code
Working bin:http://jsbin.com/dikifipelo/1/
var string = "1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20." ;
string = string.replace(/(([^\.]+\.){5})/g, "$1<br/>");
Works with any type and length of characters between the dots.
Explanation:
The pattern /(([^.]+.){5})/g can be broken down as such:
[^\.] - any character that is not a dot
[^\.]+ - any character that is not a dot, one or more times
[^\.]+\. - any character that is not a dot, one or more times, followed by a dot
([^\.]+\.){5} - any character....dot, appearing five times
(([^\.]+\.){5}) - any...five times, capture this (all round brackets capture unless told not to, with a ?: as the first thing inside them)
the /g/ flag makes it so that the whole string is matched - ie, all matches are found
"$1" represents the results of the first group (or bracket)
so, the replace function finds all instances of the pattern in the string, and replaces them with the match itself + a line break (br).
Once you learn regular expressions, life is never the same.

Categories