3

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.")
3
  • 1
    for (let i = 0; i < colors.length; i++) { // body of your loop } Commented Aug 27, 2018 at 17:54
  • is a very simple filter using Array#filter() and String#indexOf() or String#includes() all of which are easy to research by themselves Commented Aug 27, 2018 at 17:55
  • colors.filter(color => sillySentence.indexOf(color) !== -1).length Commented Aug 27, 2018 at 17:58

7 Answers 7

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This is probably the smartest answer right now. Please explain how match works. He is new to JS. Also, he need a forloop...even tho this is the smartest answer it's not a valid one
@TamoDev not for everyone : / , I've added an explanation
1

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:

  • This builds a regexp of the form /\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).
  • It uses Array.join to build that regexp.
  • It uses String.match to test the input string against that regexp.
  • It uses Array.filter to remove duplicates (see this answer)
  • the || [] 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).

Comments

0

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.

2 Comments

This code is not working completely. it doesn't pass a the test case with multiple color words ex. red blue, return one instead of 2
awesome. i tried to use .length but i messed it up somewhere and already deleted it from frustration. thanks guy!
0

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.");

Comments

0

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.

Comments

0

Simple Solution

A Simple, but inefficient, solution is:

  • Lowercase the string
  • Split the string by spaces and punctuation.

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);

Efficient Solution

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);

1 Comment

Your code doesn't pass all the test cases. Try blue red blue black and returns 2, instead of 3
-1

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

3 Comments

This code doesn't work. It also doesn't count if you put more than one color
@TamoDev which part does not work? Share that scenario
nvm it works! Idk how gave you the -1 tho.. but this answer works pretty solid. Good job!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.