30 Days Of JavaScript.12E
Day 12. Regular Expressions_Exercise
👟Level 1.
1. Calculate the total annual income of the person from the following text.
const txt = 'He earns 4000 euro from salary per month, 10000 euro annual bonus, 5500 euro online courses per month.'
const pattern = /\d+/g;
const matches = txt.match(pattern);
console.log(matches); // (3) ['4000', '10000', '5500']
let [perMonth1, annualBonus, perMonth2] = matches;
let annualIncome = (+perMonth1 + +perMonth2) * 12 + +annualBonus;
console.log(annualIncome); // 124000
Notice that the matches
array has string elements. So to actually calculate the salary, I should convert those strings into numbers. I can use parseInt()
or Number()
in the place of +
. To use the matched values for calculation, I destructured the matched array into three different variables.
2. The position of some particles on the horizontal x-axis -12, -4, -3 and -1 in the negative direction, 0 at origin, 4 and 8 in the positive direction. Extract these numbers and find the distance between the two furthest particles.
const txt = 'The position of some particles on the horizontal x-axis -12, -4, -3 and -1 in the negative direction, 0 at origin, 4 and 8 in the positive direction.';
const pattern = /.\d+/g;
const points = txt.match(pattern);
const sortedPoints = [];
for (let element of matches) {
element = Number(element);
sortedPoints.push(element);
}
const distance = sortedPoints[points.length - 1] - sortedPoints[0];
/* using Math methods
const distance = Math.max(...sortedPoints) - Math.min(...sortedPoints);
*/
console.log(points); // ['-12', '-4', '-3', '-1', ' 0', ' 4', ' 8']
console.log(sortedPoints); // [-12, -4, -3, -1, 0, 4, 8]
console.log(distance); // 20
I used .
to also extract ‘-‘ in front of each numbers. From the text, the numbers were already sorted so I didn’t have to sort them again. If the numbers are mixed, I can use sort()
like below:
sortedPoints.sort((a, b) => a - b);
3) Write a pattern which identifies if a string is a valid JavaScript variable.
A variable name is invalid when:
-
it begins with a number
-
it has special characters except dollar sign($) and underscore(_)
-
it has a space between words
function is_valid_variable(str) {
const pattern1 = /^\d/;
const pattern2 = /[^A-Za-z0-9$_]/;
bool1 = pattern1.test(str);
bool2 = pattern2.test(str);
if (bool1||bool2) {
return 'Invalid';
} else {
return 'Valid';
}
}
console.log(is_valid_variable('first_name')); // Valid
console.log(is_valid_variable('first-name')); // Invalid
console.log(is_valid_variable('1first_name')); // Invalid
console.log(is_valid_variable('firstname')); // Valid
console.log(is_valid_variable('first name')); // Invalid
pattern1
checks if the name starts with number. pattern2
checks if the name includes other characters than alphabets, numbers, and special characters that are allowed($
and _
). It will also return ‘Invalid’ to a variable name which has space in it. If at least one pattern matches the variable name(and returns true
), it is invalid variable.
👟Level 2.
1. Write a function called tenMostFrequentWords which get the ten most frequent word from a string?
-
Expected output: ``` console.log(tenMostFrequentWords(paragraph)); [ {word:’love’, count:6}, {word:’you’, count:5}, {word:’can’, count:3}, … {word:’If’,count:1} ]
console.log(tenMostFrequentWords(paragraph, 3));
[ {word:’love’, count:6}, {word:’you’, count:5}, {word:’can’, count:3} ]
```js
const paragraph = `I love teaching. If you do not love teaching what else can you love. I love Python if you do not love something which can give you all the capabilities to develop an application what else can you love.`
function tenMostFrequentWords(str, number) {
const pattern = /[^A-Za-z ]/g;
const onlyWords = str.replace(pattern, '');
const wordIndex = [...new Set(onlyWords.split(' '))];
const wordsAndCounts = [];
for (i = 0; i < wordIndex.length; i++) {
let word = new RegExp(`${wordIndex[i]}`, 'g');
wordsAndCounts[i] = {word: wordIndex[i], count: onlyWords.match(word).length}
}
const sortedWordCounts = wordsAndCounts.sort((a, b) =>
b.count - a.count
);
const printOut = sortedWordCounts.filter((object) =>
sortedWordCounts.indexOf(object) < number);
return printOut;
}
console.log(tenMostFrequentWords(paragraph, 10));
To only extract word characters, I removed all the characters except A-Z and a-z, and space by using replace()
method. Then I splitted the onlyWords
string by a space, and used Set()
to get the index of words.
I have to put
new
in the front when usingSet
orRegExp
.
To put a variable as a regular expression, I must use RegExp
constructor. Using string templates(${}
) without using the constructor wouldn’t work.
// it returns null
let matches = /${wordIndex[i]}/g
wordsAndCounts[i] = {word: wordIndex[i], count: onlyWords.match(matches).length}
- Mistakes I’ve been through
1) I first declared the wordsAndCounts
array inside the for
loop, and an empty array was returned when I logged the array to console. Because I declared the array with const
, it wouldn’t change unless I move the array to the outside of the loop.
2) Again, when using higher order functions, if the statement is single lined, I shouldn’t use curly braces. Otherwise, the function wouldn’t be executed.
👟Level 3.
1. Write a function which cleans the following text(remove all punctuations). After cleaning, count three most frequent words in the string.
const sentence = '%I $am@% a %tea@cher%, &and& I lo%#ve %tea@ching%;. There $is nothing; &as& mo@re rewarding as educa@ting &and& @emp%o@wering peo@ple. ;I found tea@ching m%o@re interesting tha@n any other %jo@bs. %Do@es thi%s mo@tivate yo@u to be a tea@cher!?'
// cleaning the text
function cleanText(str) {
const pattern = /[^A-Za-z ]/g;
const cleanedText = str.replace(pattern, '');
return cleanedText;
}
console.log(cleanedText);
// I am a teacher and I love teaching There is nothing as more rewarding as educating and empowering people I found teaching more interesting than any other jobs Does this motivate you to be a teacher
// counting three most frequent words in the string
function mostFrequentWords(str) {
const cleanedText = cleanText(str);
const wordIndex = [...new Set(cleanedText.split(' '))];
const wordsAndCounts = [];
for (i = 0; i < wordIndex.length; i++) {
let word = new RegExp(`${wordIndex[i]+ ' '}`, 'g');
wordsAndCounts[i] = { word: wordIndex[i], count: cleanedText.match(word).length };
}
const sortedWordCounts = wordsAndCounts.sort((a, b) =>
b.count - a.count
);
const printOut = sortedWordCounts.filter((object) =>
sortedWordCounts.indexOf(object) < 3);
return printOut;
}
console.log(mostFrequentWords(sentence));
/* (3)[
{word: 'I', count: 3},
{word: 'a', count: 2},
{word: 'and', count: 2}] */
- Mistakes I’ve been through
The function first returned {word: ‘a’, count: 16} as the most frequent language. I guess the match()
searched all the single character ‘a’s in the sentence. So I had to find a way to put a variable into regular expression, and to find an exact match.
First I tried to use ^...$
, but I couldn’t find how to put these anchors in RegExp
constructor. I finally figured out how. Since I was matching each unique words with the cleanedText
, I had to add a space(‘ ‘) to only extract the exact ‘a’. At the beginning I wrote like below:
let word = new RegExp(`${wordIndex[i] }`, 'g');
I thought just adding a space inside the string template would be fine, but it didn’t work. So I used a plus sign to explicitly add a space in a pattern, and it worked.
let word = new RegExp(`${wordIndex[i] + ' '}`, 'g');
Leave a comment