I'm trying to build a JavaScript devowelizer, but I'm producing an infinite loop.
I'm hoping someone on Stack Overflow can help?
The code =>
let userWord = prompt("Type a word to devowelize: ");
userWord = Devowelize(userWord);
alert(userWord);
function Devowelize(word) {
for (let i = 0; i <= word.length; i++) {
let eatChars = "aeiou"
for (let i2 = 0; i2 <= eatChars.length;) {
if (word[i] == eatChars[i2] &&
word[i] != "") {
word = word.replace(word[i], "");
} else {
i2++;
}
}
}
return word
}
You are using here for (let i = 0; i <= word.length; i++) this part i <= word.length isn't correct because you will try to access the array word using the i index after that in your code so in the last iteration you will access an index which is not defined by your array the last index of an array in javascript is always arrayLength-1 if you access an item which is out of the array you will get an undefined as value which will generates an infinte loop in your case you have done the same thing here for (let i2 = 0; i2 <= eatChars.length;) but the first loop is the responsible of the infinite loop in your code
Your solution is almost there, but you're trying to solve this problem in a very roundabout way. Let's make it a bit easier to understand.
In JavaScript, you can easily check if a string contains another string. For example, if we wanted to check if a character was in a string, we could do this:
let eatChars = "aeiou"
eatChars.includes('e') === true
So knowing that we can do that in a single statement, let's reuse some of the code you've got and substitute the character 'e' for the characters in your word.
let outWord = ""
const eatChars = "aeiou"
// '<= word.length' becomes this, because the string positions only go up to 'word.length - 1
for (let i = 0; i < word.length; i++) {
if (!eatChars.includes(word[i])) { // so the character isn't a vowel
outWord += word[i]
}
}
return outWord
The comments mention learning about 'map' and 'filter'. I'd recommend using a reducer for this if you wanted to be fancy! You could try something like this:
const devowel = (word) => Array.from(word).reduce((out, currentCharacter) => ...)
Related
I want to iterate through a string until a null character is found (\0), like how we do in C language. I have listed down the steps which I have tried below.
let exampleValue = 'abcdef';
let i = 0;
// Trial 1
while (exampleValue[i] !== '\0') {
i++;
// This seems to go on infinitely
}
// Trial 2
while (exampleValue[i] !== '\0'.charCodeAt(0)) {
i++;
// This seems to go on infinitely
}
// Trial 3
while (exampleValue[i] !== \0) {
i++;
// This throws an invalid character error
}
// Trial 4
while (exampleValue[i] !== undefined) {
i++;
// This seems to work
}
Based on the above samples, Trial 4 seems to work. Can I continue using Trial 4 for my desired output or is there a better way to solve my problem?
EDIT:
I apologize for not specifying my problem, I want to print each letter of the string by iterating through it without using exampleValue.length
EDIT 2:
After I read tadman's comment, I got to know Javascript's do not terminate their string using a null character but instead it stores it's keeps track of it characters and stores the length seperately.
If you just want to count the length then just do exampleValue.length
let exampleValue = 'abcdef';
let i = exampleValue.length;
console.log(i);
Or if you want to perform some logic using that char, you can try:
let exampleValue = 'abcdef';
let i = 0;
exampleValue.split('').forEach(c => {
console.log(c);
i++;
// Your logic here.
});
console.log(i);
Or using plain for loop:
let exampleValue = 'abcdef';
let i = 0;
for (let x = 0; x < exampleValue.length; x++) {
console.log(exampleValue.charAt(i));
i++;
// Your logic here.
}
console.log(i);
You are getting these cases because you will never get an '\0' in your string so the loop will run infinitely.
And the last case is working fine because after the last character of your string, the next character will be undefined.
Now, if you want to loop through the string then you can do it this way:
let exampleValue = 'abcdef';
let i = 0;
while (i < exampleValue.length ) {
console.log(exampleValue[i]);
i++;
}
Since you didn't say exactly what you realy want... If you want to print the individual characters,
let exampleValue = 'abcdef';
for(var j = 0; j < exampleValue.length; j++){
console.log(exampleValue[j]);
}
And if you are just interested in the number of elements:
int i = exampleValue.length;
console.log(i)
I know there are some similar questions to this one, but my one concerns just a particular solution to the problem (the problem: for a string input, return an object that counts the number of times each character (key) occurs in the string (value)):
function countAllCharacters(str) {
var obj = { };
for (var i = 0, j = str.length; i < j; i++) {
obj[str[i]] = (obj[str[i]] || 0) + 1;
} return obj
}
I'm familiar with object notation and looping through an array, but I'm not sure what is going in line 4, where the code is presumably assigning some numeric value to the object key. Specifically, I don't get this bit:
(obj[str[i]] || 0) + 1;
Thanks for your help!
I'm working on some codewars problems and I came to this 'remove noise thing', I guess the point is to escape backslash \ and use replace method, which was easy. But I didn't want to use replace, instead I found myself in trouble trying to remove items with splice method.
Funny thing is, when I debug in Chrome dev tools, step by step I see items get removed, but console.log spits out certain characters($/·|ªl) problematic to remove, and at the end gets returned and join with those characters. Why is that?
function removeNoise(str) {
var base = "%$&/#·#|º\ª";
var arr = str.split('');
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
var condition = base.indexOf(item);
if(condition + 1) {
//works like a charm
//arr[i] = '';
arr.splice(i,1);
//this thing wont work
//when debugging it removes the items from the array
//console log print no removing
}
}
return arr.join('');
}
removeNoise('he%$&/#·#|º\ª\llo'); //=> $/·|ªllo
You're using splice to remove entries from your array, but you're then incrementing i for the next loop. If you remove the entry at index 5 from a 10-entry array, what was the entry at index 6 is now at index 5 (of what's now a 9-entry array), so you don't want to increment your index.
The solution is to use a while loop and only update i if you don't splice:
function removeNoise(str) {
var base = "%$&/#·#|º\ª";
var arr = str.split('');
var i = 0;
while (i < arr.length) {
var item = arr[i];
var condition = base.indexOf(item);
if (condition + 1) {
// Remove this entry, reuse same value for 'i'
arr.splice(i,1);
} else {
// Don't remove this entry, move to next
++i;
}
}
return arr.join('');
}
var result = removeNoise('he%$&/#·#|º\ª\llo');
var pre = document.createElement('pre');
pre.appendChild(
document.createTextNode(result)
);
document.body.appendChild(pre);
You're removing characters from your array. This will throw your indexer variable i out of sync with the characters you want to test. Easy way to fix is to start at the end of the array working your way to the beginning.
Change your for loop to this.
for(var i = arr.length -; i <= 0; i--) {
function removeNoise(str) {
var base = "%$&/#·#|º\ª";
var arr = str.split('');
for(var i = arr.length - 1; i <= 0 ; i--) {
var item = arr[i];
if(base.indexOf(item) >= 0) {
//remove the offending character
arr.splice(i,1);
}
}
return arr.join('');
}
removeNoise('he%$&/#·#|º\ª\llo'); //=> $/·|ªllo
I'm trying to count the number of times certain words appear in the strings. Every time I run it I get a
uncaught TypeErro: undefined is not a function
I just actually need to count the number of times each "major" appears.
Below is my code:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray.search("Multimedia") === true)
{
multimedia += 1;
}
}
console.log(multimedia);
Here is my csv file which is stored in a 1d array.
"NAME","MAJOR","CLASS STANDING","ENROLLMENT STATUS"
"Smith, John A","Computer Science","Senior","E"
"Johnson, Brenda B","Computer Science","Senior","E"
"Green, Daisy L","Information Technology","Senior","E"
"Wilson, Don A","Information Technology","Junior","W"
"Brown, Jack J","Multimedia","Senior","E"
"Schultz, Doug A","Network Administration","Junior","E"
"Webber, Justin","Business Administration","Senior","E"
"Alexander, Debbie B","Multimedia","Senior","E"
"St. John, Susan G","Information Technology","Junior","D"
"Finklestein, Harold W","Multimedia","Freshman","E"
You need to search inside each string not the array. To only search inside the "Major" column, you can start your loop at index 1 and increment by 4 :
var multimedia = 0;
for(var i = 1; i < sortedarray.length; i += 4)
{
if(sortedarray[i].indexOf("Multimedia") > -1)
{
multimedia += 1;
}
}
console.log(multimedia);
What you're probably trying to do is:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray[i].indexOf("Multimedia") !== -1)
{
multimedia++;
}
}
console.log(multimedia);
I use indexOf since search is a bit of overkill if you're not using regexes.
Also, I replaced the += 1 with ++. It's practically the same.
Here's a more straightforward solution. First you count all the words using reduce, then you can access them with dot notation (or bracket notation if you have a string or dynamic value):
var words = ["NAME","MAJOR","CLASS STANDING","ENROLLMENT STATUS"...]
var count = function(xs) {
return xs.reduce(function(acc, x) {
// If a word already appeared, increment count by one
// otherwise initialize count to one
acc[x] = ++acc[x] || 1
return acc
},{}) // an object to accumulate the results
}
var counted = count(words)
// dot notation
counted.Multimedia //=> 3
// bracket notation
counted['Information Technology'] //=> 3
I don't know exactly that you need this or not. But I think its better to count each word occurrences in single loop like this:
var occurencesOfWords = {};
for(var i = 0; i < sortedarray.length; i++)
{
var noOfOccurences = (occurencesOfWords[sortedarray[i]]==undefined?
1 : ++occurencesOfWords[sortedarray[i]]);
occurencesOfWords[sortedarray[i]] = noOfOccurences;
}
console.log(JSON.stringify(occurencesOfWords));
So you'll get something like this in the end:
{"Multimedia":3,"XYZ":2}
.search is undefined and isn't a function on the array.
But exists on the current string you want to check ! Just select the current string in the array with sortedarray[i].
Fix your code like that:
for(var i = 0; i < sortedarray.length; i++)
{
if(sortedarray[i].search("Multimedia") === true)
{
multimedia += 1;
}
}
console.log(multimedia);
I'm attempting to teach myself javascript. I chose something I assumed was simple, but ran into problems relatively quickly.
I'm attempting to search a string for another string given by the user.
My code so far is:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = [];
var one = 0;
var two = 0;
var k = 0;
var sourceSearch = function(text) {
for(i = 0; i < source.length; i++) { //for each character in the source
if(source[i] === searchString[0]) { //if a character in source matches the first element in the users input
one = source.indexOf(i); //confused from here on
for(p = searchString.length; p > 0; p--) {
}
}
}
};
sourceSearch(searchString);
My idea was:
check to see if the first loop finds a character that matches the first character in the user input
if it matches, check to see if the next X characters after the first match the next X characters in the source string
if they all match, push them to the hits array
My problem: I have no idea how to iterate along the arrays without nesting quite a few if statements, and even then, that wouldn't be sufficient, considering I want the program to work with any input.
Any ideas would be helpful. Thanks very much in advance.
Note: There are a few un-used variables from ideas I was testing, but I couldn't make them work.
You can try:
if (source.indexOf(searchString) !== -1) {
// Match!
}
else
{
//No Match!
}
As the other answers so far point out, JavaScript strings have an indexOf function that does what you want. If you want to see how it's done "by hand", you can modify your function like this:
var sourceSearch = function(text) {
var i, j, ok; // always declare your local variables. globals are evil!
// for each start position
for(i = 0; i < source.length; i++) {
ok = true;
// check for a match
for (j = searchString.length - 1; ok && j >= 0; --j) {
ok = source[i + j] === searchString[j];
}
if (ok) {
// searchString found starting at index i in source
}
}
};
This function will find all positions in source at which searchString was found. (Of course, you could break out of the loop on the first success.) The logic is to use the outer loop to advance to each candidate start position in source and use the inner loop to test whether that position actually is the position of a match to searchString.
This is not the best algorithm for searching strings. The built-in algorithm is much faster (both because it is a better algorithm and because it is native code).
to follow your approach, you can just play with 2 indexes:
var sourceSearch = function(text) {
j = 0;
for(i = 0; i < source.length; i++) {
if(source[i] === text[j]) {
j++;
} else {
j = 0;
}
if (j == text.length) {
console.log(i - j); //this prints the starting index of the matching substring
}
}
};
These answers are all pretty good, but I'd probably opt for something like this:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = source.split(searchString);
var hitsCount = hits.length - 1;
This way you have all of the data you need to figure out where each hit occurred in he source, if that's important to you.