In this weekly series, I will be taking out coding problems from CodeWars and sharing a step-by-step tutorial on how exactly I was able to solve it on my first trial. It is important to keep in mind that my solution may not be in-line with modern practices and techniques, however it is going to be correct. Which is all that really matters lol.
This is an initiative I thought up recently and I hope it helps beginners learn how to program with JavaScript.
So, let's dive in!
Who likes it?
Today's challenge is going to be quite interesting. If you use social media platforms like Facebook, you should by now know of the 'likes' feature where images and posts get liked by users and readers.
In this challenge, we are going to be creating a function which returns different customized messages depending on the number of likers a post gets.
Here are the rules:
likes[] // "No one likes this"
likes["Jack"] // "Jack likes this"
likes["Jack", "Jacob"] // "Jack and Jacob likes this"
likes["Jack", "Jacob", "Jill"] // "Jack, Jacob and Jill likes this"
likes["Jack", "Jacob", "Jill", "John"] // "Jack, Jacob and 2 others liked this"
As you can see, the likes()
function takes in an array of users who likes a post and returns a different message depending on if one, two, three or four and more users liked the post.
I pulled this test out of a 6 kyu challenge on CodeWars.
Without further ado, let's dig in!
SOLUTION
The first step I always take when solving a coding problem is to break them down into logical steps and representing each of these steps in pseudocode.
STEP 1: CHECKING IF ANYONE LIKED IT
Define the likes function. This function will take in Array of names (strings)
First step to take inside the function is to define an if statement: Check to see if the length of the array is falsy (that is, the array is empty and no one liked the post).
If it is empty, return a string with the meaage which says "No one likes this post"
function likes ( ...names ) {
if( !names.length) {
return "No one likes this";
}
// Continuation
STEP 2: LOOPING OVER THE ARRAY AND STORING NUMBER OF LIKERS
If we got to this point, it means that there is atleast one name present in the Array. Create a count
variable and set its value to zero. After you are done with that, loop through the list of name. For every iteration you make, increment the value of count
by one.
let count = 0;
names.forEach(name => count++);
STEP 3: CHECKING TO SEE HOW MANY LIKED
Step 2
was about looping through the array and increasing the count by one for every likers encountered.
Now, we are going to implement a chain of conditional statements which is geared towards returning a new message for every number of likers.
First statement checks if the count variable is one, which means that one person liked the post. If true, we will get the name of the sole liker and return the following message: insert_liker_name likes this post
Second statement checks if the count variable is two, which means that two people liked the post. If true, we will get the name of the two likers and return the following message: liker_1 and liker_2 likes this post
Third statement checks if the count variable is three, which means that three people liked the post. If true, we will get the name of the three likers and return the following message: liker_1, liker_2 and liker_3 likes this post
The fourth and final statement checks if the count variable is four or above, which means that at least four people liked the post. If true, we will first subtract two (i.e the people who will be displayed) from the number of likers, that is count
. Then we will get the first two names from the list of likers and return the following message: liker_1, liker_2 and remaining_numbers likes this post
if(count == 1) {
const firstName = names[0];
return `${firstName} likes this post`
} else if (count == 2) {
const firstName = names[0]
const secondName = names[1]
return `${firstName} and ${secondName} likes this post`
}
else if (count == 3) {
const firstName = names[0]
const secondName = names[1]
const thirdName = names[2]
return `${firstName}, ${secondName} and ${thirdName} likes this post`
} else {
const remainder = count - 2;
const firstName = names[0]
const secondName = names[1]
return `${firstName}, ${secondName} and ${remainder} others likes this post`
}
}
Now, lets see the full program:
function likes(...names) {
if(!names.length) {
return "No one likes this";
}
let count = 0;
names.forEach(name => count++);
if(count == 1) {
const firstName = names[0];
return `${firstName} likes this post`
} else if (count == 2) {
const firstName = names[0]
const secondName = names[1]
return `${firstName} and ${secondName} likes this post`
}
else if (count == 3) {
const firstName = names[0]
const secondName = names[1]
const thirdName = names[2]
return `${firstName}, ${secondName} and ${thirdName} likes this post`
} else {
const remainder = count - 2;
const firstName = names[0]
const secondName = names[1]
return `${firstName}, ${secondName} and ${remainder} others likes this post`
}
}
const likers = ["Jack", "Jill"]
console.log(likes(...likers));
RESULT
This simple challenge was really fun for me on the first trial and I hope it was the same for you. You can copy the code and test it yourself on JS Fiddle.
If you have a better way of solving this problem, please put it down in the comments. I'd love to check it out. If you have any suggestions, I'd love to hear it!
I will be doing this every Mondays, Wednesdays and Fridays. Follow/Subscribe to this blog to be updated. I will be tackling a new challenge in public on Friday.
Until then, friends!
P/S: If you are learning JavaScript, I recently created an eBook which teaches 50 topics in hand-written notes. Check it out here
Top comments (17)
Your function definition is wrong and doesn't match what you've stated - the function you have defined doesn't take an array at all - rather an arbitrary number of arguments that will be converted to an array. If someone were to pass an empty array to the function, rightly expecting to get the "no likes" result according to your description - it wouldn't work.
Admittedly, defining the function and calling it the way you have (using the spread operator) does make the function more flexible, but if you're going to always pass an array, or maybe extend the function to accept other parameters - then you're better off dropping the rest parameter and making the function actually accept an array rather than forming an array from its arguments
Hi, Jon.
Thank you so much for sharing your insight.
Thanks for sharing King.
You can concise this code a bit further and avoid repeating the same strings or values using temporals in Javascript.
Here is my version:
jsfiddle.net/iStealersn/12uetjgv/4/
Awesome!
Thanks for sharing
Some good improvements to make things more DRY, but the nested ternary's make my brain bleed. I feel like this would be much more legible using a switch or even just if/else statements.
Yeah I agree, had the same feeling after completion. If/Else statements make it look long while switch may definitely help gotta give a shot
If you have an improved version please share, it will be helpful
Here's a solution that takes a few more things into account:
Nice solution. This does not say "and x others" though.
Awesome!
This is even shorter and better. Thanks for sharing.
Thanks for making this post.
It's a nice idea to share question in this forum.
Here is my version. What do you guys think
It's shorter!
My version using destructuring. Criticism is welcome
This isn't necessary
No need for a loop, the number of names is always
names.length
Thank you for input.
Like I said, this is how I solved it the first time.
I always enjoy seeing the steps each person takes to accomplishing these challenges, thanks for the write up!
Thank you!