How do I count letters in JavaScript? - javascript

I have written this function (which is not working) which is supposed to count the letters in a global variable (paraText), and then insert it to count. How do I solve this?
This is a school project so I have to follow sertain rules. I have tried almost all answers but I can't get it to work :( maybe if you look at all the code you can see what I'm doing wrong.
"use strict";
var paraText = "";
var antalParagrafer = 0;
function addLetter(c) {
if(!paraText) {
addParagraph();
}
else { //add c to saved textnode
var tNod = document.createTextNode(c);
paraText.appendChild(tNod);
}
}
//function is called when enter is pressed
function addParagraph() {
/*create a new paragraph with related textnode
textnode is saved to the global textnodevariable
add paragraph to the div with id "output"
you also need to mark the paragraph with the class even/odd
depending on the class of the previous paragraph*/
var div = document.getElementById("output");
var nyParagraf = document.createElement("p");
div.appendChild(nyParagraf);
antalParagrafer += 1;
nyParagraf.className = (antalParagrafer % 2 === 0 ? 'even' : 'odd');
paraText = nyParagraf;
}
//function is called when count letters is pressed
function countLetters() {
var count=0;
for(var i = 0; i < paraText.length; i++) {
var c = paraText.charAt(i);
if (c >= 'a' && c <= 'z') count++;
}
return count;
}

I'd just strip out the non-letters and then use the length of what's left:
var count = paraText.replace(/[^a-zA-Z]/g, '').length;

Your function works otherwise fine (although it's perhaps not as elegant as it could be), but count = count ++ is wrong; either use
count++;
or
count = count + 1;

The statement count = count++ doesn't increase the counter, because the value of count++ is what's in the variable before it is increased, so you increse the variable, then assign back the value that was before.
Using a simple comparison gives better performance than using a regular expression for each character in the string:
function countLetters() {
var count=0;
for(var i = 0; i < paraText.length; i++) {
var c = paraText.charAt(i);
if (c >= 'a' && c <= 'z') count++;
}
return count;
}

Related

Calculate sentences using function in Javascript

I have come across a question about calculating sentences using a form in HTML, but I wanted to work out the function first to see if it would work. Here is my function that I have not been able to get it working in jsfiddle (https://jsfiddle.net/jdloomis/fxt81ynu/2/):
var numSentences = 0;
function calSentences(longString) {
var length = longString.length;
var sentence = '';
for (var i = 0; i < length; i++) {
sentence += longString[i];
if (longString[i] == '.') {
numSentences++;
sentence = '';
}
}
}
console.log(calSentences("This is a sentence. My second sentence."));
I have been able to figure out most of the functions and what they do in my book except this one and a word count without using .split, I will post that one in another post if I cannot figure it out.
You were so close with your attempt! All you forgot to do is return the number of sentences with return numSentences:
var numSentences = 0;
function calSentences(longString) {
var length = longString.length;
var sentence = '';
for (var i = 0; i < length; i++) {
sentence += longString[i];
if (longString[i] == '.') {
numSentences++;
sentence = '';
}
}
return numSentences;
}
console.log(calSentences("This is a sentence. My second sentence."));
Hope this helps! :)
Your code is correct, but you are not returning anything from your function.
Also, keep var numSentences local to your function, so that it's reset to 0 each time you run your function. Otherwise, you are adding on to the previous calculation each time you run the function.
function calSentences(longString) {
var numSentences = 0;
var length = longString.length;
var sentence = '';
for (var i = 0; i < length; i++) {
sentence += longString[i];
if (longString[i] == '.') {
numSentences++;
sentence = '';
}
}
return numSentences;
}
console.log(calSentences("This is a sentence. My second sentence."));

cannot detect error. Where is the infinite loop occurring?

// JavaScript Document
var person = prompt("GIVE INPUT", "");
var count = 0;
var array = person.split(",");
var freq = [];
var words = [];
//freq.fill(0);
//words.fill("");
//window.alert(freq[0]);
var i = 0, j = 0;
while (array.length > 0) {
var temp = array[0];
while (j < array.length) {
if (temp == array[j]) {
count = count + 1;
array.splice(j, 1);
//console.log(array);
j = 0;
}
else {
j = j + 1;
}
}
freq[freq.length] = count;
count = 0;
words[words.length] = temp;
}
window.alert(freq + "\n" + words);
The problem is that whenever I run it an infinite loop occurs and no output is shown, I cannot find the error please help if possible. This code is for finding the frequency of the words in a input string with words separated by commas. thank u.
You just need to put var i=0,j=0; inside the while !
while(array.length>0)
{var i=0,j=0;
Working fidddle
You're resetting your loop variable j to 0 on each iteration. This condition if(temp==array[j]) never fails so j is always reset to 0, so while(j<array.length) is always true.
After coming out of the inner While loop, you need to reset j to zero. As the incremental value of j is not allowing it to go again inside the inner loop So array.length is not reducing And we are getting an infinite loop.
// JavaScript Document
var person = prompt("GIVE INPUT", "");
var count=0;
var array = person.split(",");
var freq = new Array();
var words = new Array();
//freq.fill(0);
//words.fill("");
//window.alert(freq[0]);
var i=0,j=0;
while(array.length>0)
{
var temp=array[0];
while(j<array.length)
{
if(temp==array[j])
{
count=count+1;
array.splice(j,1);
//console.log(array);
j=0;
}
else
{
j=j+1;
}
}
freq[freq.length]=count;
count=j=0;
words[words.length]=temp;
}
window.alert(freq+"\n"+words);
It's where for is more useful for consistency. You can replace inner while loop by this for loop:
for(j=a.length-1; j>=0; j--)
if(temp==a[j]) {
count=count+1;
a.splice(j,1);
}
Nevertheless, overall complexity of your counting method can be reduced with data structure like map.
Essential part of your script can be reduced to this:
var counter = new Map();
for (i in array)
counter.set(array[i], (counter.get(array[i])||0)+1);
var freq = Array.from(counter.values());
var words = Array.from(counter.keys());

Function takes a string and returns an object of the letters and number of occurrences -javascript - Homework Warning

Im working with this challenge question and I am struggling with the number count. I can get it work to return the position in the string, but not the actual letter count. Any help is appreciated.
Question -
Write a function named letterCount that takes a string and returns an
object with the letters and the number of their occurrences.
My Code so far -
var stringCount = "Hello";
function letterCount(string) {
var stringObject = {};
for (var i = 0; i < string.length; i++) {
stringObject[string[i]] = [i];
}
return stringObject;
}
letterCount(stringCount);
You have done almost everything right, only problem is the assignment part, which you need to do this way:
var stringCount = "Hello";
function letterCount(string) {
var stringObject = {};
for (var i = 0; i < string.length; i++) {
stringObject[string[i]] = ((stringObject[string[i]]) ? stringObject[string[i]] : 0) + 1;
}
return stringObject;
}
console.log(letterCount(stringCount));
So technically, what happens in the line:
stringObject[string[i]] = ((stringObject[string[i]]) ? stringObject[string[i]] : 0) + 1;
The program checks if that particular index exists in the object.
If it doesn't exists (not defined, undefined), it assigns 0.
If it exists, it takes the same value.
It adds 1 to the above value.
The same above line can be written this way:
// Check if the current key exists.
if (typeof stringObject[string[i]] == "undefined") {
// If it doesn't, initialise it 1.
stringObject[string[i]] = 1;
} else {
// If it exists, increment it.
stringObject[string[i]] = stringObject[string[i]] + 1;
// Another way:
// stringObject[string[i]]++;
}

Why does my code work with underscore.js but not when I use Ramda.js?

I am new to Javascript, I am doing a coding challenge to learn more about the language. This is not school related or anything like that, totally for my own personal growth. Here is the challenge:
Return the sum of all odd Fibonacci numbers up to and including the
passed number if it is a Fibonacci number.
I have spent the past 2 evenings working on solving this challenge. When I run my code using underscore.js it works. When I use Ramda.js it says NaN. I would think both would return NaN. I'm very surprised that I can get the correct answer from one and not the other. Any insights would be greatly appreciated!
var R = require('ramda');
function sumFibs(num) {
var fib_Arr = [];
var new_Arr = [];
var total = 0;
// I use this to tell if the fib num is greater than 2
var the_Bit = "false";
// This is used to keep track of when to stop the loop
var fib_Num = 0;
// THIS WORKS FROM HERE
// This loop generates a list of fibonacci numbers then pushes them to the fib_Arr
for(var i = 0; total < num; i++){
if (i < 1){
fib_Arr.push(0);
}
else if (i === 1){
fib_Arr.push(i);
fib_Arr.push(1);
}
else if (i === 2){
fib_Arr.push(2);
the_Bit = "true";
}
else if (the_Bit === "true"){
temp_Arr = R.last(fib_Arr,2);
temp_Arr = temp_Arr[0] + temp_Arr[1];
fib_Arr.push(temp_Arr);
total = R.last(fib_Arr);
}
// Generating the fib Array works TO HERE!!!!
}
// console.log(fib_Arr); // Print out the generated fibonacci array
// if last Array element is greater than the original in
var last_Element = R.last(fib_Arr);
if (last_Element > num){
console.log("The last element of the array is bigger!");
fib_Arr.splice(-1,1); // This removes the last item from the array if it is larger than the original num input
}
// This loop removes all of the EVEN fibonacci numbers and leaves all of the ODD numbers
for (var j = 0; j < fib_Arr.length; j++){
if (fib_Arr[j] % 2 !== 0){
new_Arr.push((fib_Arr[j]));
}
}
// This checks if the original input num was a
if (num % 2 !== 0){
new_Arr.push(num);
}
else{
console.log("The original num was not a Fibonacci number!");
}
// if last Array element is the same as the original input num
var last = R.last(fib_Arr);
if (last === num){
console.log("Removing the last element of the array!");
new_Arr.splice(-1,1); // This removes the last item from the array if it is the same as the original num input
}
// Now to add all of the numbers up :-)
for (var k = 0; k < new_Arr.length; k++){
console.log("This is fib_Num: " + fib_Num);
// console.log(fib_N`);
fib_Num = fib_Num += new_Arr[k];
}
return fib_Num;
}
// TEST CASES:
// console.log(sumFibs(75025)); //.to.equal(135721);
console.log(sumFibs(75024)); //.to.equal(60696);
You have a problem on these lines :
temp_Arr = R.last(fib_Arr,2);
temp_Arr = temp_Arr[0] + temp_Arr[1];
Besides the fact that R.last does not take a second argument (that will not fail though), you are using temp_arr as an array, when it is a number. Therefore, temp_arr gets a NaN value.
You are probably looking for R.take (combined with R.reverse) or R.slice.
By changing :
temp_Arr = R.last(fib_Arr,2);
with :
temp_Arr = R.take(2, R.reverse(fib_Arr));
or with :
temp_Arr = R.slice(fib_Arr.length - 2, fib_Arr.length)(fib_Arr);
or with (bonus play with a reduce from the right) :
temp_Arr = R.reduceRight(function(arr, elem) {
return arr.length < 2 ? [elem].concat(arr) : arr;
}, [])(fib_Arr);
We get :
sumFibs(75024) === 60696
For the record, here's how you do this problem:
function fibSumTo(n) {
var f1 = 1, f2 = 1, sum = 1, t;
while (f2 <= n) {
if (f2 & 1) sum += f2;
t = f1 + f2;
f1 = f2;
f2 = t;
}
return sum;
}
There's really no need for any sort of library because there's really no need for any sort of data structure.
var _ = require('underscore');function sumUpFibs (number){
arr_of_fibs = [1,1];
current = 1; //cursor for previous location
while (true){
var num = arr_of_fibs[current] + arr_of_fibs[current - 1];
if (num <= number) {
arr_of_fibs.push(num);
current++;
} else {
break;
}
}
console.log(arr_of_fibs);
var total = 0;
_.each(arr_of_fibs, function(fib){
total += fib;
})
return total;}console.log(sumUpFibs(75025));
This may be a better implementation... Though I know you're just starting so I don't want to come off as mean : D.... Also, maybe check your test cases too.

Showing unique characters in a string only once

I have a string with repeated letters. I want letters that are repeated more than once to show only once.
Example input: aaabbbccc
Expected output: abc
I've tried to create the code myself, but so far my function has the following problems:
if the letter doesn't repeat, it's not shown (it should be)
if it's repeated once, it's show only once (i.e. aa shows a - correct)
if it's repeated twice, shows all (i.e. aaa shows aaa - should be a)
if it's repeated 3 times, it shows 6 (if aaaa it shows aaaaaa - should be a)
function unique_char(string) {
var unique = '';
var count = 0;
for (var i = 0; i < string.length; i++) {
for (var j = i+1; j < string.length; j++) {
if (string[i] == string[j]) {
count++;
unique += string[i];
}
}
}
return unique;
}
document.write(unique_char('aaabbbccc'));
The function must be with loop inside a loop; that's why the second for is inside the first.
Fill a Set with the characters and concatenate its unique entries:
function unique(str) {
return String.prototype.concat.call(...new Set(str));
}
console.log(unique('abc')); // "abc"
console.log(unique('abcabc')); // "abc"
Convert it to an array first, then use Josh Mc’s answer at How to get unique values in an array, and rejoin, like so:
var nonUnique = "ababdefegg";
var unique = Array.from(nonUnique).filter(function(item, i, ar){ return ar.indexOf(item) === i; }).join('');
All in one line. :-)
Too late may be but still my version of answer to this post:
function extractUniqCharacters(str){
var temp = {};
for(var oindex=0;oindex<str.length;oindex++){
temp[str.charAt(oindex)] = 0; //Assign any value
}
return Object.keys(temp).join("");
}
You can use a regular expression with a custom replacement function:
function unique_char(string) {
return string.replace(/(.)\1*/g, function(sequence, char) {
if (sequence.length == 1) // if the letter doesn't repeat
return ""; // its not shown
if (sequence.length == 2) // if its repeated once
return char; // its show only once (if aa shows a)
if (sequence.length == 3) // if its repeated twice
return sequence; // shows all(if aaa shows aaa)
if (sequence.length == 4) // if its repeated 3 times
return Array(7).join(char); // it shows 6( if aaaa shows aaaaaa)
// else ???
return sequence;
});
}
Using lodash:
_.uniq('aaabbbccc').join(''); // gives 'abc'
Per the actual question: "if the letter doesn't repeat its not shown"
function unique_char(str)
{
var obj = new Object();
for (var i = 0; i < str.length; i++)
{
var chr = str[i];
if (chr in obj)
{
obj[chr] += 1;
}
else
{
obj[chr] = 1;
}
}
var multiples = [];
for (key in obj)
{
// Remove this test if you just want unique chars
// But still keep the multiples.push(key)
if (obj[key] > 1)
{
multiples.push(key);
}
}
return multiples.join("");
}
var str = "aaabbbccc";
document.write(unique_char(str));
Your problem is that you are adding to unique every time you find the character in string. Really you should probably do something like this (since you specified the answer must be a nested for loop):
function unique_char(string){
var str_length=string.length;
var unique='';
for(var i=0; i<str_length; i++){
var foundIt = false;
for(var j=0; j<unique.length; j++){
if(string[i]==unique[j]){
foundIt = true;
break;
}
}
if(!foundIt){
unique+=string[i];
}
}
return unique;
}
document.write( unique_char('aaabbbccc'))
In this we only add the character found in string to unique if it isn't already there. This is really not an efficient way to do this at all ... but based on your requirements it should work.
I can't run this since I don't have anything handy to run JavaScript in ... but the theory in this method should work.
Try this if duplicate characters have to be displayed once, i.e.,
for i/p: aaabbbccc o/p: abc
var str="aaabbbccc";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 ){
return obj;
}
}
).join("");
//output: "abc"
And try this if only unique characters(String Bombarding Algo) have to be displayed, add another "and" condition to remove the characters which came more than once and display only unique characters, i.e.,
for i/p: aabbbkaha o/p: kh
var str="aabbbkaha";
Array.prototype.map.call(str,
(obj,i)=>{
if(str.indexOf(obj,i+1)==-1 && str.lastIndexOf(obj,i-1)==-1){ // another and condition
return obj;
}
}
).join("");
//output: "kh"
<script>
uniqueString = "";
alert("Displays the number of a specific character in user entered string and then finds the number of unique characters:");
function countChar(testString, lookFor) {
var charCounter = 0;
document.write("Looking at this string:<br>");
for (pos = 0; pos < testString.length; pos++) {
if (testString.charAt(pos) == lookFor) {
charCounter += 1;
document.write("<B>" + lookFor + "</B>");
} else
document.write(testString.charAt(pos));
}
document.write("<br><br>");
return charCounter;
}
function findNumberOfUniqueChar(testString) {
var numChar = 0,
uniqueChar = 0;
for (pos = 0; pos < testString.length; pos++) {
var newLookFor = "";
for (pos2 = 0; pos2 <= pos; pos2++) {
if (testString.charAt(pos) == testString.charAt(pos2)) {
numChar += 1;
}
}
if (numChar == 1) {
uniqueChar += 1;
uniqueString = uniqueString + " " + testString.charAt(pos)
}
numChar = 0;
}
return uniqueChar;
}
var testString = prompt("Give me a string of characters to check", "");
var lookFor = "startvalue";
while (lookFor.length > 1) {
if (lookFor != "startvalue")
alert("Please select only one character");
lookFor = prompt(testString + "\n\nWhat should character should I look for?", "");
}
document.write("I found " + countChar(testString, lookFor) + " of the<b> " + lookFor + "</B> character");
document.write("<br><br>I counted the following " + findNumberOfUniqueChar(testString) + " unique character(s):");
document.write("<br>" + uniqueString)
</script>
Here is the simplest function to do that
function remove(text)
{
var unique= "";
for(var i = 0; i < text.length; i++)
{
if(unique.indexOf(text.charAt(i)) < 0)
{
unique += text.charAt(i);
}
}
return unique;
}
The one line solution will be to use Set. const chars = [...new Set(s.split(''))];
If you want to return values in an array, you can use this function below.
const getUniqueChar = (str) => Array.from(str)
.filter((item, index, arr) => arr.slice(index + 1).indexOf(item) === -1);
console.log(getUniqueChar("aaabbbccc"));
Alternatively, you can use the Set constructor.
const getUniqueChar = (str) => new Set(str);
console.log(getUniqueChar("aaabbbccc"));
Here is the simplest function to do that pt. 2
const showUniqChars = (text) => {
let uniqChars = "";
for (const char of text) {
if (!uniqChars.includes(char))
uniqChars += char;
}
return uniqChars;
};
const countUnique = (s1, s2) => new Set(s1 + s2).size
a shorter way based on #le_m answer
let unique=myArray.filter((item,index,array)=>array.indexOf(item)===index)

Categories