Reputation: 31
So I have been learning javascript for two months now and I'm doing some precourse work and got stuck on this question. I know I need a for a loop. but I am completely lost and there doesn't seem to be a comparable problem anywhere to learn from. the problem is://Given a string, write a program that counts how many colors are used in that string. For the purposes of our challenge, let's say all the available colors are: blue, green, gray, red, black, and purple.
So here is the code I have so far
//declaring values and user input
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const sillySentence = prompt("Tell me a colorful Rhyme: ");
//for loop to solve the problem
//start output
console.log("You Listed " + x + " colors in your rhyme.")
Upvotes: 3
Views: 118
Reputation: 14927
Here's a version using regular expressions. This code will only accept colors as words, e.g. bluegreen
will not match anything.
Edit: now takes into account unique colors only.
const colors = ['blue', 'green', 'gray', 'red', 'black', 'purple'];
const sillySentence = prompt('Tell me a colorful Rhyme:');
const result = (sillySentence.match(
new RegExp('(\\b' + colors.join('|') + '\\b)', 'g'))
.filter((value, index, self) => self.indexOf(value) === index)
|| []).length;
console.log(result);
Explanation:
/\b(blue|green|red)\b/
, which basically says: a word among blue, green and red (\b
is the word boundary character, preventing thisisthebluecolor
from matching blue
).Array.join
to build that regexp.String.match
to test the input string against that regexp.Array.filter
to remove duplicates (see this answer)|| []
basically says: if the regexp doesn't match, consider the result of String.match
an empty array (so that .length
, the size of that result, will return 0).Upvotes: 1
Reputation: 5260
If a for loop is not a necessary requirement, here you have a different approach without one. If elements of color array have only letters you could use match() that returns an array of matches, to build the regex we convert the colors array into string and replace the ,
for |
that means or in a regex so the result is something like /blue|green|gray/, then we count the length of the matches:
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const sillySentence = prompt("Text: ");
var r = new RegExp(colors.toString().replace(/,/g, "|"), "g");
var found = (sillySentence.match(r) > 0) ? sillySentence.match(r).length : 0;
console.log(found);
This example won't work if we have ,
in the strings of colors.
Upvotes: 1
Reputation: 4884
A Simple, but inefficient, solution is:
Then you iterate through the words and try to find the colors. Example:
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const sillySentence = prompt("Tell me a colorful Rhyme: ");
const colorCount = new Set();
const words = sillySentence.toLowerCase().split(/[\s,.:;]+/);
for (let i = 0; i < words.length; i++) {
const word = words[i];
if (colors.indexOf(word) >= 0) {
colorCount.add(word);
}
}
console.log(colorCount.size);
A more efficient solution is to populate a Set and use it to quickly lookup the colors:
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const sillySentence = prompt("Tell me a colorful Rhyme: ");
const colorSet = new Set();
colors.forEach(color => colorSet.add(color));
const colorCount = new Set();
const words = sillySentence.toLowerCase().split(/[\s,.:;]+/);
for (let i = 0; i < words.length; i++) {
const word = words[i];
if (colorSet.has(word)) {
colorCount.add(word);
}
}
console.log(colorCount.size);
Upvotes: 0
Reputation: 18525
You also could just use regular expression
group match (/(blue)/
for example) and simply count the length ... this way you do not have to worry about special characters, splitting to words etc.
Here is an example:
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const rhyme = "I love blue, and red, but mostly blue!! and sometimes green! and red... NO gray!"
console.log(colors.reduce((r,c) => {
let matches = rhyme.match(new RegExp(`(${c})`, 'gi'))
return matches ? Object.assign(r, { [c]: matches.length }) : r
},{}))
Note: I wraped the whole thing in a reduce
just so I can return an object with the counts etc but I am sure you get the picture.
Upvotes: 0
Reputation:
While this is not a correct answer because you are asking for a forloop I wanted to share another way to do things in JS since you are new into JS.
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const sillySentence = prompt("Tell me a colorful Rhyme: ");
let count = 0;
sillySentence.split(' ').find((color)=> {
if (colors.includes(color) !== -1) {
count += 1;
}
});
console.log("You Listed " + count + " colors in your rhyme.");
Upvotes: 0
Reputation: 1623
You can use something like this:
const colors = ["blue", "green", "gray", "red", "black", "purple"];
var sillySentence = prompt("Tell me a colorful Rhyme: ");
let x = 0;
if (sillySentence) {
sillySentence = sillySentence.toLowerCase();
for (let i = 0; i < colors.length; i++) {
if (sillySentence.indexOf(colors[i]) >= 0) {
x += 1;
}
}
}
//start output
console.log("You Listed " + x + " colors in your rhyme.");
It'll be best to loop through number of colors as they will be less than number of words of the rhyme and it will count unique colors only.
Upvotes: 0
Reputation: 50346
Get the value of the prompt and split it into an array, then iterate that array and for each value in that array see if there exist a same element in colors array, if it is so then increase value of x by 1
const colors = ["blue", "green", "gray", "red", "black", "purple"];
const sillySentence = prompt("Tell me a colorful Rhyme: ");
let x = 0;
sillySentence.split(' ').forEach(function(item) {
if (colors.indexOf(item) !== -1) {
x += 1;
}
});
console.log("You Listed " + x + " colors in your rhyme.")
Note: This program is not taking care of unique color in the prompt value. For example if any color appears twice , it will consider it as 2
Upvotes: -1