counting words of each sentence in a long string, jquery - javascript

I am trying to count the words in each sentence from a long string. What I get is just the number of the sentences. I found some solution in C# and Ruby but they are not for me:-))
I am really new to java-script. Any help much appreciated. The code below:
the output is according:
Words: 1 in sent: 1
Words: 0 in sent: 2
Words: 1 in sent: 3
Words: 1 in sent: 4
Words: 1 in sent: 5
Words: 1 in sent: 6
the word counter is not increasing! Most probably it's something simple.
Thank you in advance.
var text1 = $('#textarea1').val();
var gaps = [];
var wordsC = 0;
var wordsTot = 0;
var tempC = 0;
var sents = text1.split('.');
for (var elem in sents)
{
tempC += 1;
wordsC = elem.split(" ").length;
wordsTot += wordsC;
if (tempC == 2) {
wordsC -= 1;
wordsTot -= 1;
}
document.write("<br />Words: " + wordsC + " |in sent: " + tempC + " sent");
};
document.write("<br />words total : " + wordsTot + "<br />" );

You shouldn't enumerate an array with for...in. text1.split('.'); is producing an array, which you are trying to enumerate with for...in. The value of elem on each iteration of the for...in is one of the the array indexes as a string ('0' on the first iteration, '1' on the second and so on). You'll even end up with some of the Array prototype methods and other things up the prototype change.
For pre ES6 environments, try:
for (var i = 0; i < sents.length; i++)
{
tempC += 1;
wordsC = sents[i].split(" ").length;
wordsTot += wordsC;
if (tempC == 2) {
wordsC -= 1;
wordsTot -= 1;
}
document.write("<br />Words: " + wordsC + " |in sent: " + tempC + " sent");
}
ES6 introduced a for...of construct which does what you're trying to do:
for (let elem of sents)
{
tempC += 1;
wordsC = elem.split(" ").length;
wordsTot += wordsC;
if (tempC == 2) {
wordsC -= 1;
wordsTot -= 1;
}
document.write("<br />Words: " + wordsC + " |in sent: " + tempC + " sent");
};

var str = "There are five words here. I like turtles a lot. This is five words long. Yep.";
var split = str.split(".");
var amountOfSentences = str.charAt(str.length - 1) == "." ? split.length : split.length + 1;
var total = 0;
for (i = 0; i < amountOfSentences - 1; i++) {
$("body").append("Sentence " + (i + 1) + ": ");
for (j = 0; j < split[i].split(" ").length - 1; j++) {
total++;
}
if (i == 0) total++;
$("body").append(" " + total + "<br />");
total = 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
There are five words here. I like turtles a lot. This is five words long. Yep.
This will output:
Sentence 1: 5
Sentence 2: 5
Sentence 3: 5
Sentence 4: 1
The end of sentence can end with a dot or not, it doesn't matter (taken account for in the var amountOfSentences). Does that work out for you?

Related

Why the Double mirror pascal star pattern is not printed?

Here is the my javascript code for printing the pattern shown below in the image.
please check the code and solve the error.
<script>
var n = prompt("Enter the number of n you want to print");
//rows = Math.floor(n / 2)
let str = ""
var i, j, k
for(i = 1; i <= n; i++){
for(j = 1; j <= i; j++){
str += "*"
}
for(k = n + 1; k >= i; k--){
str += " "
}
for(k = n + 1; k >= i; k--){
str += " "
}
for(j = 1; j <= i; j++){
str += "*"
}
str += "\n"
}
for(i = 1; i <=n + 2; i++){
for(j = n + 2; j > i; j--){
str += "*"
}
for(k = 1; k <= i; k++){
str = " "
}
for(k = 1; k <= i; k++){
str = " "
}
for(j = n + 2; j > i; j--){
str += "*"
}
str += "\n"
}
console.log(str)
</script>
I want Output like this :
but I got just 2 spaces in output
Convert your input to Number:
n = Number(n);
and then change your code as #TomLV mentioned:
var n = prompt("Enter the number of n you want to print");
//rows = Math.floor(n / 2)
n = Number(n);
let str = ""
var i, j, k
for(i = 1; i <= n; i++){
for(j = 1; j <= i; j++){
str += "*"
}
for(k = n + 1; k >= i; k--){
str += " "
}
for(k = n + 1; k >= i; k--){
str += " "
}
for(j = 1; j <= i; j++){
str += "*"
}
str += "\n"
}
for(i = 1; i <=n + 2; i++){
for(j = n + 2; j > i; j--){
str += "*"
}
for(k = 1; k <= i; k++){
str += " "
}
for(k = 1; k <= i; k++){
str += " "
}
for(j = n + 2; j > i; j--){
str += "*"
}
str += "\n"
}
console.log(str)
You are setting str equal to " " in both "k loops" in the second "i for loop".
e.g:
for(k = 1; k <= i; k++){
str = " "
}
for(k = 1; k <= i; k++){
str = " "
}
If you update those to += it works.
Some issues:
prompt returns a string, you need to convert it to a number. You can use the unary plus for that.
str = " " occurs at two places where you should have done str += " "
The generated pattern has two spaces in the center line, while you are asked to only have one space there. To make that happen have the k loops make one iteration less, and add str += " " as a separate statement outside of those loops.
The output has an empty line at the very end. This is because the second i loop is making one iteration too many.
Not a problem, but:
Use semi-colons to separate statements. Although JavaScript provides automatic semi-colon insertion, you wouldn't be the first to fall into one of the pitfalls. It is better to take control of this yourself and have the habit of adding the semi-colons.
There really is no need here to declare loop variables at the top. Just declare them at the moment you need them with only the scope they need to have.
I'll assume that the number of lines in the output is supposed to be n*2+1 and that there was no error concerning that aspect.
Corrected code:
// Convert string to number using unary plus:
const n = +prompt("Enter the number of n you want to print");
let str = "";
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= i; j++) {
str += "*";
}
// Reduced the number of iterations here:
for (let k = n; k >= i; k--) {
str += " ";
}
// Add one space for the center column
// that is the only column without asterisks
str += " ";
// Reduced the number of iterations here:
for (let k = n; k >= i; k--) {
str += " ";
}
for (let j = 1; j <= i; j++) {
str += "*";
}
str += "\n";
}
// Reduced number of iterations. i should not become equal to n + 2
for (let i = 1; i <= n + 1; i++) {
for (let j = n + 2; j > i; j--) {
str += "*";
}
// Reduced the number of iterations here:
for (let k = 1; k < i; k++) {
str += " "; // Fixed assignment
}
// Add one space for the center column
// that is the only column without asterisks
str += " ";
// Reduced the number of iterations here:
for (let k = 1; k < i; k++) {
str += " "; // Fixed assignment
}
for (let j = n + 2; j > i; j--) {
str += "*";
}
str += "\n";
}
console.log(str);
Note that JavaScript has functions that can facilitate this proces, like "*".repeat(i) can be used instead of a loop to produce the same string.
So then it becomes:
const n = +prompt("Enter the number of n you want to print");
let str = "";
for (let i = 1; i <= n + 1; i++) {
str += "*".repeat(i) + " ".repeat(2*n + 3 - 2*i) + "*".repeat(i) + "\n";
}
for (let i = n; i >= 1; i--) {
str += "*".repeat(i) + " ".repeat(2*n + 3 - 2*i) + "*".repeat(i) + "\n";
}
console.log(str);
And you could also reuse the results of the first loop to derive the second half of the output by storing the lines in an array. You can then reverse that array to get the second half (without the middle line):
const n = +prompt("Enter the number of n you want to print");
const arr = Array.from({length: n + 1}, (_, i) =>
"*".repeat(i+1) + " ".repeat(2*(n-i)+1) + "*".repeat(i+1)
);
console.log([...arr, ...arr.reverse().slice(1)].join("\n"));

Make integer in For Loop Superscript

Okay, so obviously you can't make an integer a superscript since it's a number. I need you guys. How would I take the integer from the loop and make it into a string so I can .sup() it. I'm open to using an array.
Here is the original
var n;
for (let i = 0; i <= 31; i++) {
n = Math.pow(2, i);
document.write("2 ^ " + i + " = " + n + "<br>");
}
Here is with an array (NOT FUNCTIONING!)
var n, myArray = [];
for (let i = 0; i <= 31; i++) {
myArray.push(Math.pow(2, i));
}
for (var j = 0; j <= 31; j++) {
document.write("2" + myArray[j].sup() + " = " + n + "<br />");
}
Thoughts?
sup is a method on String. So, you have to convert the number to a String first:
myArray[j].toString().sup()
Note: in many cases anything is converted to String implicitly, but not when you call a method on an object.
var n, myArray = [];
for (let i = 0; i <= 31; i++) {
myArray.push(Math.pow(2, i));
}
for (var j = 0; j <= 31; j++) {
document.write("2" + myArray[j].toString().sup() + " = " + n + "<br />");
}

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 code runs fine... almost all the time

I have come across a problem that I cannot seem to resolve. Please take a look at the code below:
<script>
function createFunctions() {
var first = ["", "", ""];
var second = ["", "", ""];
var func = ["", ""];
var sign = ["", ""];
for (i = 0; i < 3; i++) {
first[i] = (Math.round(Math.random() * 9) + 1);
second[i] = (Math.round(Math.random() * 9) + 1);
sign[i] = (Math.round(Math.random()));
if (sign[i] == "1") {
sign[i] = '+';
} else {
sign[i] = '-';
}
if (first < 2) {
func[i] = 'f(x) = x ' + sign[i] + ' ' + second[i] + '<p>';
} else {
func[i] = 'f(x) = ' + first[i] + 'x ' + sign[i] + ' ' + second[i] + '<br>';
}
}
for (i = 0; i < 3; i++) {
document.getElementById("createFunctions").innerHTML += 'Function ' + [i + 1] + ': ' + func[i];
}
//whichFunction=
findAnswers(first, second, sign);
}
function findAnswers(first, second, sign, rand) {
var num = ["", "", ""];
rand = (Math.round(Math.random() * 1));
document.getElementById("findAnswers").innerHTML = 'Which <b>one (or more)</b> of these functions holds true, when plugged in with the following <b>values of x</b>? (' + [rand + 1] + ')<br>';
for (i = 0; i < 3; i++) {
num[i] = (Math.round(Math.random() * 9));
}
for (i = 0; i < 3; i++) {
ans = 0;
if (sign[rand] == "+") {
ans = [first[rand] * num[i]] + second[rand];
} else {
ans = [first[rand] * num[i]] - second[rand];
}
document.getElementById("findAnswers").innerHTML += [i + 1] + '. You put in a ' + num[i] + ': ' + ans + '<br>';
}
}
</script>
<BODY onload=createFunctions()>
<b>A Machine Called Effex</b>
<p><input type="button" value="New Examples" onclick="history.go(0)" VALUE="Refresh"></p>
<p id="createFunctions"></p>
<p id="findAnswers"></p>
Everything works great. Except occasionally, when calculating the function, the code multiplies by x, and then simply concatenates the second value onto the first, instead of adding (or subtracting).
You should change [first[rand]*num[i]] to (first[rand]*num[i]).
The [] bracket is instantiating an array with only one value (the product of your multiplication) and then you're 'adding' the array to a number, which forces the engine to cast the array to a string and concatenate the string with the number you're 'adding'.
To illustrate, consider the code below. It also instantiates an array but casts it to a number using the unary + operator. This will result in a numerical value and not an array, so your code will work as expected.
+[first[rand]*num[i]]
To further illustrate what's happening, consider the code below. It too instantiates a single-element array, but by appending it with [0], we specify the (numerical) value of that element and so the engine is not forced to cast the array to a string when you use the + operator.
[first[rand]*num[i]][0]

Grade Statistics Calculator

I'd like to get some help on my javascript code. I made a grade statistics calculator that shows results on:
Min – Max student grade
Min – Max student average
Min – Max course grade
Min – Max course average grade
You can access it live here --> http://jsbin.com/qirefe/edit?html,css,js,output and press the "Show Results" button to see my output. (You can change the names and the grades to get a different output)
My problem is that I cannot figure out why it doesn't show the correct course names on the Min - Max course grade, although it displays the grades right. Also I cannot figure out why it calculates wrongly the min and max course average grade and displays the corresponding courses name wrong..
Any help will be very appreciated :)
The .js code:
var Course0 = Array(6);
var Course1 = Array(6);
var Course2 = Array(6);
var Student = Array(6);
var CMap = [Course0, Course1, Course2];
var NMap = ["Course0", "Course1", "Course2"];
var showResults = function () {
var Rows = document.getElementsByClassName("srow");
for (var i = 1; i < Rows.length - 1; i++) {
var values = Rows[i].getElementsByTagName("input");
Student[i - 1] = values[0].value;
for (var j = 1; j < values.length; j++) {
CMap[j - 1][i - 1] = values[j].value;
}
}
var MinID = MaxID = AvgMinID = AvgMaxID = 0;
var Min = Max = AvgMin = AvgMax = undefined;
for (var i = 0; i < Student.length; i++) {
var c0 = Course0[i];
var c1 = Course1[i];
var c2 = Course2[i];
var lessonMin = Math.min(c0, c1, c2);
var lessonMax = Math.max(c0, c1, c2);
if ((lessonMin <= Min) || (typeof Min === "undefined")) {
MinID = i;
Min = lessonMin;
}
if ((lessonMax >= Max) || (typeof Max === "undefined")) {
MaxID = i;
Max = lessonMax;
}
var Avg = Math.avg(c0, c1, c2);
if ((Avg < AvgMin) || (typeof AvgMin === "undefined")) {
AvgMinID = i;
AvgMin = Avg;
}
if ((Avg > AvgMax) || (typeof AvgMax === "undefined")) {
AvgMaxID = i;
AvgMax = Avg;
}
}
var Wrapper = document.getElementById("student-results");
Wrapper.innerHTML = "";
Wrapper.innerHTML += "<span>The Student with lower grade is: " + Student[MinID] + ", Equals To " + Min + "</span>";
Wrapper.innerHTML += "<span>The Student with higher grade is: " + Student[MaxID] + ", Equals To " + Max + "</span>";
Wrapper.innerHTML += "<hr />";
Wrapper.innerHTML += "<span>The Student with lower average grade is: " + Student[AvgMinID] + ", Equals To " + AvgMin + "</span>";
Wrapper.innerHTML += "<span>The Student with higher average grade is: " + Student[AvgMaxID] + ", Equals To " + AvgMax + "</span>";
var CourseMin = CourseMinID = CourseMax = CourseMaxID = CourseAvgMin = CourseAvgMinID = CourseAvgMax = CourseAvgMaxID = 0;
CourseMin = CourseMax = CourseAvgMin = CourseAvgMax = undefined;
for (var i = 0, j = 0; i < Student.length; i++, j += .5) {
var c0 = Course0;
var c1 = Course1;
var c2 = Course2;
var CheckMin = Math.min(c0[i], c1[i], c2[i]);
if (CourseMin > CheckMin || (typeof CourseMin === "undefined")) {
CourseMin = CheckMin;
CourseMinID = i;
}
var CheckMax = Math.max(c0[i], c1[i], c2[i]);
if (CourseMax < CheckMax || (typeof CourseMax === "undefined")) {
CourseMax = CheckMax;
CourseMaxID = parseInt(j);
}
var Avg = Math.avg(c0[i], c1[i], c2[i]);
if (Avg < CourseAvgMin || (typeof CourseAvgMin === "undefined")) {
CourseAvgMin = Avg;
CourseAvgMinID = j;
}
if (Avg > CourseAvgMax || (typeof CourseAvgMax === "undefined")) {
CourseAvgMax = Avg;
CourseAvgMaxID = parseInt(j);
}
}
console.log(CourseMaxID);
Wrapper.innerHTML += "<hr />";
Wrapper.innerHTML += "<span>The Course with lower grade have: " + NMap[CourseMinID] + ", Equals To " + CourseMin + "</span>";
Wrapper.innerHTML += "<span>The Course with higher grade have: " + NMap[CourseMaxID] + ", Equals To " + CourseMax + "</span>";
Wrapper.innerHTML += "<hr />";
Wrapper.innerHTML += "<span>The Course with lower average grade have: " + NMap[CourseAvgMinID] + ", Equals To " + CourseAvgMin + "</span>";
Wrapper.innerHTML += "<span>The Course with higher average grade have: " + NMap[CourseAvgMaxID] + ", Equals To " + CourseAvgMax + "</span>";
return null;
};
Math.avg = function () {
var Avg = 0;
var table = arguments;
for (var i = 0; i < table.length; i++) {
Avg += parseFloat(table[i]);
}
return parseFloat(Avg / table.length);
};
After examining the output of CourseMaxID and CourseMinID in the console, CourseMinID has an index of 3, but NMap only has 3 values (indexed as 0, 1, 2). So I believe this is why, for example, you are seeing:
"The Course with lower grade have: " + NMap[CourseMinID] + ", Equals To " + CourseMin; is undefined -- because the index is out of bounds.
Here's a fix for your issues with CourseMinID and CourseMaxID:
Change the definition of CourseMinID to Math.floor(j)-1;
And change CourseMaxID to be equal to Math.ceil(j);
Your call to parseInt() on a float value didn't appear to be having the intended consequence.
I'm not entirely sure why you're choosing to increment j by 0.5 each time, but from observation I noticed that for CourseMax/CourseMinID, you wanted to use the computations I noted above.
Another note, for the course average values, you are in fact outputting the student's averages. So you will want to change your logic there. It looks to me like you are giving the horizontal row of grades as parameters to the average function:
var Avg = Math.avg(c0[i], c1[i], c2[i]);
That's not what you want to parse in to Avg for course average grades. I would define another Avg function (let's call it newAvg() here) that takes as input a single array (not multiple arguments), and then call Math.Min/Math.Max on newAvg(c0), newAvg(c1), newAvg(c2).
Here's an updated jsbin link with working functionality for course averages. Overview of changes: newAvg() has been defined to take in and operate on one parameter. Keep track of indices of CourseAvgMax and CourseAvgMin. Note that I've removed some of the other operations you had earlier in this jsbin link to make it easier for me to isolate what I was working on. Hope you find it useful!

Categories