Probably very messy and not most efficient way


#1

This is probably very messy and not most efficient way. It gets answer: The most repeated (14 times) word is: the.
First I thought that I used only methods covered in previous lessons, but looks like this is not true.

The most repeated (14 times) word is: the

story = story.replace(/[\W_]+/g," ");
let storyLowerCase = story.toLowerCase();
let storyWordsLower = storyLowerCase.split(' ');


//array will hold number of times word is repeating
 let   x = [];
//array will hold repeating words
 let y = [];

let count = 0;

      for (storyWordsLowerInd = 0; storyWordsLowerInd < storyWordsLower.length; storyWordsLowerInd++) {
     
     for (storyWordsLowerIndex = 0; storyWordsLowerIndex < storyWordsLower.length;     storyWordsLowerIndex++) {


        if (storyWordsLower[storyWordsLowerIndex] === storyWordsLower[storyWordsLowerInd] ) {

          count++; 
           y.push(count);
           x.push(storyWordsLower[storyWordsLowerIndex]);
         }

    }
 storyWordsLowerIndex++;
 count = 0;
 }
 

function findMax () {       
return Math.max.apply(Math, y);

}
console.log("\n");
console.log(`The most repeated (${findMax()} times) word is: ${x[y.indexOf(findMax())]}`);

Mini Linter Item 8
#2

Did we cover Regular Expressions in any lessons?


#3

:slight_smile: well, I do not know what that is… I googled how to remove non-alphabetical things, and then I checked that this ‘replace’ bit is in string methods category, that was covered, but I guess it is something more:) well sorry, I am totally beginner :slight_smile: And I admit that (/[\W_]+/g," ") was copy pasted and not understood. I look forward to know more about it and Regular Expressions and everything else.


#4

If you learn nothing else, learn this… Never use code you do not understand fully. Better that you use a less efficient solution that you wrote and understand.


#5

Ok, That is true. Lesson learned. I can’t solve it yet, will come back to it later. It just felt that it is missing so little, but yes, first I have to understand that little, that might be even big:) Thanks


#6

I tried to practice more with what I know, looks like it works, but would be nice to know if there is something very wrong with it. Thanks

function greatestNumberWord () {
  
let storyWords = story.split(' ');
let storyLowerCase = story.toLowerCase();
let storyWordsLower = storyLowerCase.split(' ');
let char = storyLowerCase.split('');
let storyWordsLowerChar = char.filter(function(char) { 
if (char !== '"' && char !== '"' && char !== "'" && char !== "/\/" && char !== '.' && char !== '!' && char !== '?' && char !== ',' && char !== '-') {
  return char;
}
 }); 
   
storyNewString = storyWordsLowerChar.join('');
let newStringWords = storyNewString.split(' ');
  
//array will hold repeating words
 let   x = [];

//array will hold number of times word is repeating
 let y = [];

let count = 0;

for(newStringWordsInd = 0; newStringWordsInd < newStringWords.length; newStringWordsInd++) {     
  for (newStringWordsIndex = 0; newStringWordsIndex < newStringWords.length; newStringWordsIndex++) {
    if (newStringWords[newStringWordsIndex] === newStringWords[newStringWordsInd] ) {
      count++; 
      y.push(count);
      x.push(newStringWords[newStringWordsIndex]);
    } 
  }       
newStringWordsIndex++;
count = 0;
}

let max = 0;
  
for (yIndex = 0; yIndex < y.length; yIndex++) {
  if(y[yIndex] > max) {
    max = y[yIndex];
  }
}
   
console.log(`The most repeated (${max} times) word is: ${x[y.indexOf(max)]}.`)
}
greatestNumberWord();

#7

filter() is an iterator with a built in conditional construct. That means no if expression needed.

Array.filter(function (x) { 
    return x expression; // when expression true
})

Consider also that your code has a lengthy logical expression that could be reduced to a single list (array) of unwanted characters.

const punctuation = "\"\\'.,?!-/".split("");    // edited

We can iterate over this list and run the filter of the text on each character.

Note that single quotes might not work as expected.

Tip: If an empty string ("") is used as the separator, the string is split between each character. Array.prototype.split()

let storyChars = story.toLowerCase().split("");

The story characters is a temporary data structure of our own devising, and we can manipulate how we like without preserving the discarded parts. In the following loop we will perform an in-place mutation of the list, filtering only valid characters. The final value will be the filtered array. Upon that array we may run our other filter, mode map, or histogram functions.

punctuation.forEach(function (p) {
    storyChars = storyChars.filter(function (x) {
        return x !== p;
    });
});

which can be refactored to arrow function syntax since it is simple and does not call upon this or the arguments object.

punctuation.forEach( p => {
    storyChars = storyChars.filter( x => x !== p);
});

As you have done in your code, we can join this all up to form one long string of words, and then split on the space characters, giving us our working array of words.

words = storyChars.join('').split(' ');
console.log(words.length);
// <- 188

Having reduced the story to this list of words, we can proceed to whatever task is next. If you wish to preserve this list then spin off a slice to create an independent copy.

const wordList = words.slice();

Now, moving into the forbidden waters of Regular Expressions (on the proviso they have not been taught in this course), we can boil words down to a single expression…

let words = story.toLowerCase().split("").filter(function(x) {  
    return x.match(/[.,'":;?!\/\\\-]/) === null;  
}).join('').split(' ');
console.log(words.length);
// <- 188

Or in ES2015 syntax…

let words = story.toLowerCase().split("").filter( x => x.match(/[.,'":;?!\/\\\-]/) === null).join('').split(' ');
console.log(words.length);
// -< 188

To reiterate, this not advisable, and the above iterator methods are the more appropriate, given the nature of the unit.

Keep working on your remaining code while making use of the iterators at hand to lessen the code load. Reduce the number of moving parts and identifiable variables and you lighten your own load.


#8

Thank You very much, for such a detailed revision , really appreciate it . I will keep working on it.


#9

You’re welcome!

One should add that there is no harm in spreading one’s wings. When you are feeling confident with the use of iterators, then by all means explore other options, but read up extensively before adopting regular expressions. They are tricky, resource intensive and too easily taken for granted. Whatever use we make of them needs to be extensively tested and should leave no questions in the mind of the author or reader.

Study the following example that converts a regular expression method to an iterative method.

story.split("").filter(x => /[.:?!]/.test(x)).length
// <- 12

Just like above, we can create a list of the four full-stop characters…

const fullStops = ":.?!".split("");

Now iterate with forEach() like earlier…

let storyChars = story.toLowerCase().split("");
let sentences = 0;
fullStops.forEach(s => { 
    sentences += storyChars.filter(x => x === s).length;
});
console.log(sentences);
// <= 12

There is a lot to digest in this and the earlier posts. Be sure to take the time necessary before departing from this unit.

Mini-Linter study


#10

Yes, no I feel very much, that more I look in to small things bigger they become. When I tried to console log " const punctuation = “”’.,;:?!\/-".split(""); " it gave me not what I expected, then I red all about escape characters, but I am still stuck :smiley: with \/\ ‘\’, ‘/’ .What is the last \ for? … As I understand \ creates (inserts) one \ , then when console logging it inserts \ as escape character and we get ‘\’ But then why it doesn’t insert \ for everything .,;:? Or do I understand it wrong… and then third \ is for escaping / and the last… I feel stupid now:) but that keeps me going:)


#11
"\"'.,;:?!\\\/\-"

The first escapement is the double quote. Escaping it makes it a printable character, not a string delimiter. None of the other characters need to be escaped except the backslash. I had only copied the characters from the earlier regex. My bad.

const punctuation = "\"\\'.,?!-/".split("");

Over time, read up on what characters are special to the regex engine, and therefore requiring escapement. I’ve not given this any review in a long time so mistakes are possible. Like you said, little details. Regexs are chalk full of those.

Mini-Linter


#12

Thank You, now it makes sense. And “Escaping it makes it a printable character” means paper printable?


#13

Or any other. Printable as opposed to special. Anything printable can be pattern matched, or can be stored in a variable, or can be logged, etc.

Consider the following example in which we gererate HTML dynamically…

val = 'user input';
div = "<div class\"someclass\">" + val + "</div>";
document.getElementById('someid').innerHTML = div;

Without the escapes the string will end after class and the rest will be a syntax error. With the escapes it gets written to the DOM tree as,

<div class"someclass">user input</div>