Create a function counting how many valid smileys there are in an array.
The solution seems to need these functions:
Then loop over all smileys and split/check each of them.
splitSmiley = smiley => smiley.split("")
If the separator is ""
the string is converted to an array of each of its characters.
checkEyes = splittedSmiley => {
validEyes = [':',';']
eye = splittedSmiley[0]
return validEyes.includes(eye)
}
Note you do need an explicit return keyword.
Make sure you understand the in
operator. For arrays you must specify the index number instead of the index value which might be confusing if you’re used to other languages like Python or R. So this:
eyes in validEyes
would not work because it will return false
. You have to use the includes
method of Array
.
checkMouth = splittedSmiley => {
validMouths = [')','D']
mouth = splittedSmiley[splittedSmiley.length - 1]
return validMouths.includes(mouth)
}
At first I used here but pop()
changes the array its called upon. This results in bugs difficult to find.
let counterSmileys = 0
arr.forEach(smiley => {
const splittedSmiley = splitSmiley(smiley)
const eyesOk = checkEyes(splittedSmiley)
const mouthOk = checkMouth(splittedSmiley)
let noseOk = true // if no nose it's ok
if (splittedSmiley.length === 3) {
// 3 means eyes, nose and mouth
noseOk = checkNose(splittedSmiley)
}
if (eyesOk && noseOk && mouthOk) {
counterSmileys += 1
}
})
A running counter for the number of smileys. Could have put these if
statements in seperate functions to make things more clear.
counterSmileys
is a let
because it can change, if not I would have used const
.
In the end it was too bad the tests on Codewars kept failing and I couldn’t see which tests failed exactly. This made it impossible to debug.
From the solutions with best practices this one was pretty readable. He created a set of rules as separate functions feeding them into a filter
function like this:
const countSmileys = smileys =>
smileys.filter(smiley =>
smileyIsValid(smiley) &&
smileyHasValidEye(smiley) &&
smileyHasValidNose(smiley) &&
smileyHasValidMouth(smiley)
).length
It almost reads like plain English.
Functions in Javascript can be defined in multiple ways:
Regular function:
function () {}
Arrow function:
() => {}
Compared to a regular function an arrow function:
this
(so no separate execution context)At first sight the syntax of the arrow function seems almost the same as for a regular function. But there are shortcuts if:
In this example I also took advantage of the scoping rules by defining helper functions like splitSmiley
within the overarching countSmileys
function:
The nested (inner) function is private to its containing (outer) function.