Count the smiley faces! Regular Expressions?

Count the smiley faces! Regular Expressions?
0

challenge : https://www.codewars.com/kata/583203e6eb35d7980400002a
I’m wondering if anyone know how to solve this challenge with regular expressions? because in the challenge, it has a “regular expression” tag attached to it.

i passed this with my code :

//return the total number of smiling faces in the array
function countSmileys(arr) {
if ( arr.length === 0 )  { 
  return 0;
}
let incr = 0;
let validSmileys = [":)",";)",":D",";D",":-D",":~D",":-)",":~)",";~D",";~)",";-D",";-)"]
for (let face of arr) { 
  if (validSmileys.includes(face)) { 
    incr++;
  }
}
return incr;
}

countSmileys([";~D" , ":o>" , ";~)" , ":)" , ";~>" , ":(" , ";D"])


// : or ;
// - or ~
// ) or D.

you need a pattern that is tiny bit complex and the test method, so it return true/false if it matches or not

remember that you create a class of characters using square parenthesis,
so if you write [abc] it matches any of the letters inside it

1 Like

@Gerwyn Solving with a regular expression is fairly simple.

function countSmileys(arr) {
  const matches = arr.join('').match(/[:;][-~]?[D)]/g);
  return matches ? matches.length : 0;
}

However, if you are not using the regular expression, I think instead of using the array as the lookup, it would be faster to use an object lookup.

function countSmileys(arr) { 
  const validSmileys = {
    ":)": true, ";)": true, ":D": true,
    ";D": true, ":-D": true, ":~D": true,
    ":-)": true, ":~)": true, ";~D": true,
    ";~)": true, ";-D": true, ";-)": true
  };
  return arr.filter(chars => validSmileys[chars]).length;  
}
1 Like

I learned regex but its a bit cloudy for me since i don’t use it much. your example reinforced the practicality of them for me. as for the OOP example, i tried and they worked but im wondering though, shouldn’t they return an array of true values? like [true,true…] since validSmileys[chars] gives the value of the property which is true. that’s the only thing im confused of really.

I used test method instead of match and it works fine too.

function countSmileys(arr) {

let faceRegex= /[;:][~-]?[)D]/
let incr = 0;
for (face of arr) { 
  if (faceRegex.test(face)) { 
    incr++;
  }
}
return incr;
}

countSmileys([':)',':(',':D',':O',':;'])

I always have to refer to the MDN documentation of RegEx. Very helpful.

i prefer w3schools tbh. it just shows a practical example immediately

1 Like

The filter method returns a new array of the values in which the callback function returns a “truthy” value. filter does not change the original string values of the array to Booleans. The validSmileys[chars] returns either true or undefined, so for the following call:

countSmileys([':)',':(',':D',':O',':;']);

arr.filter(chars => validSmileys[chars]) returns:

[ ':)', ':D' ]

Adding the .length to the end, just counts the number of items in the filtered array.

right so it only filters the ones in the array. and the ones that only are filtered are the ones who had return true?

Yes, that is how it works.