Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find how many times a char is repeated in a string and remove those repeated chars by a dynamic number

I would like to write a function that recieves two parameters: String and Number. The function will return another string that is similar to the input string, but with certain characters removed. The function will remove characters from consecutive runs of the same character, where the length of the run is greater than the input parameter.

for example:

"aaab", 2 => "aab"

"aabb", 1 => "ab"

"aabbaa", 1 => "aba"

What I did:

function doSomething(string,number) {
    let repeatCount = 0
   
    debugger;
    for (let i = 0; i < string.length; i++) {
     if(string[i] == string[i+1]){
         repeatCount++
     } 
      if(repeatCount > number ){
         string.replace(string[i],'') 
      }  
    }

    console.log(string)

}
doSomething('aaab',2)

The console.log(string) prints 'aaab' but I want it to print 'aab' because the number is 2 and the char 'a' is repeated 3 times.

If there is another better way to do it , I will be happy to learn.

like image 221
Bar Levin Avatar asked Jan 24 '23 12:01

Bar Levin


1 Answers

If there is another better way to do it, I will be happy to learn.

You could go with a .replace() approach and a regular expression with a backreference to match consecutive letters. Then you can use .slice() to remove the additional letters to get it to the defined length like so:

function shorten(string,number) {
  return string.replace(/(.)\1+/g, m => m.slice(0, number))
}

console.log(shorten("aaab", 2))// => "aab"

console.log(shorten("aabb", 1))// => "ab"

console.log(shorten("aabbaa", 1))// => "aba"

The above regular expression will match any character and group it (.). This matched character is then checked for again to see if it is repeated one or more times by using \1+. The replacement function will then be invoked for each consecutive runs of letters, which you can trim down to your desired length by using .slice().

For example, take the string aabbaa. The regular expression tries to find consecutive runs of characters. The (.) would match any character, in this case, it finds "a" and puts it into a "capture group" called "1". Now the regular expression tries to find whether “a” is followed by one or more “a” characters by checking if the grouped (ie the character “a”) follows it one or more times. This is done using \1+. The first section of the aabbaa string that this regular expression matches is "aa", as we match the “a”, capture it, and find that it is repeated with \1+. When a match is found, the function m => m.slice(0, number) is ran. This function takes the match (m), which in this case is "aa", and returns the sliced version of it, giving "a". This then replaces the "aa" we matched from the original string with the value returned, thus causing "aa" to be converted to "a" (note this conversion doesn't modify the original string, it occurs in the new string that gets returned by the replace method). The /g at the end of the regular expression means repeat this for the entire string. As a result, our regular expression moves on and finds "bb". The function then gets called again but this time with m set as "bb", causing "bb" to be converted to "b". Lastly, we match "aa", this causes "aa" to get converted to "a". Once replace has finished going through the entire string, it returns the result with the returned values (as well as the part of the original string it didn’t modify) and so it gives "aba"

like image 137
Nick Parsons Avatar answered Feb 13 '23 17:02

Nick Parsons