Olena Horal
Olena Horal

Reputation: 1214

Count repeated letters in a string

I'm stuck with the following problem: I need to find repeated characters in a string. Basically what I want is regular expression that will match like that

hello - ["ll"];
here  - ["ee"];
happiness   -  ["pp","ss"];
pupil  -  ["pp"];

I have the one that matches consecutive repeated characters

  /([a-z])\1+/g

Also the one that will match repeated chars and everything between them like this one

   /([a-z])(?:.*)\1+/g

But cant figure out the correct one.

Upvotes: 6

Views: 50538

Answers (9)

Om Mangukiya
Om Mangukiya

Reputation: 1

let str = "I have not received any notification."
let obj = {}
for (let st of str.toLowerCase()) {
  if (obj[st]) {
    obj[st]++;
  } else {
    obj[st] = 1;
  }
}

Upvotes: 0

Force Bolt
Force Bolt

Reputation: 1221

//Try this method

const countRepeatChar = (str) => {
  let obj = {};

  if (str) {
    for (let i = 0; i < str.length; i++) {
      if (obj[str[i]]) {
        obj[str[i]] += obj[str[i]];
      } else {
        obj[str[i]] = 1;
      }
    }
    console.log(obj);
  }
};
countRepeatChar("aabcddeee");

Upvotes: 0

Sachin Tripathi
Sachin Tripathi

Reputation: 1

function charCount(str){
    let arr = str.split('');
    return arr.reduce((a,p)=>{
        a[p] = a[p] ? (a[p]+1) : 1;
        return a;
    },{});
};

Upvotes: 0

Dominic Amal Joe F
Dominic Amal Joe F

Reputation: 337

This method also works well!!

let myString = 'abababc';
let result = {};
for (let str of myString) {
  result[str] = result.hasOwnProperty(str) ? result[str] + 1 : 1;
}
console.log(result);

The result will be like this {a: 3, b: 3, c: 1}

Upvotes: 4

Viswa
Viswa

Reputation: 26

var re = /([a-z])(?:.*)(\1)+/g; 
var str = ['aaaccbcdd'];
var m;
var result = new Array();

for(var i = 0; i < str.length; i++) {
  result[i] = str[i] + "->";
  while ((m = re.exec(str[i])) !== null) {
      if (m.index === re.lastIndex) {
          re.lastIndex++;
      }
      // View your result using the m-variable.
      // eg m[0] etc.
    result[i] += m[1];
    result[i] += m[2] + ",";
  }
}

document.getElementById("results").innerHTML = result.join("</br>");
<div id="results"></div>

Upvotes: 1

dawg
dawg

Reputation: 103774

You can use

([a-zA-Z]).*(\1)

Demo regex


Since you have clarified that you are looking for a solution that will handle something other than double letters in a string, you should use a non-regex approach such as:

Build an associative array with the count of the characters in the string:

var obj={}
var repeats=[];
str='banana'

for(x = 0, length = str.length; x < length; x++) {
    var l = str.charAt(x)
    obj[l] = (isNaN(obj[l]) ? 1 : obj[l] + 1);
}

console.log(obj)

Prints

{ b: 1, a: 3, n: 2 }

Then build an array of your specifications:

for (var key in obj) {
    if (obj.hasOwnProperty(key) && obj[key]>1) {
        repeats.push(new Array( obj[key]+ 1 ).join( key ));
    }
}
console.log(repeats)

Prints:

[ 'aaa', 'nn' ]

Upvotes: 9

emartinelli
emartinelli

Reputation: 1047

For your scenario you second solution seems better. You can get the second letter by other capture group

Regex you be (it is your 2nd RegEx with more one capture group):

/([a-z])(?:.*)(\1)+/g

var re = /([a-z])(?:.*)(\1)+/g; 
var str = ['hello', 'here', 'happiness', 'pupil'];
var m;
var result = new Array();

for(var i = 0; i < str.length; i++) {
  result[i] = str[i] + "->";
  while ((m = re.exec(str[i])) !== null) {
      if (m.index === re.lastIndex) {
          re.lastIndex++;
      }
      // View your result using the m-variable.
      // eg m[0] etc.
    result[i] += m[1];
    result[i] += m[2] + ",";
  }
}

document.getElementById("results").innerHTML = result.join("</br>");
<div id="results"></div>

Upvotes: 2

SpenserJ
SpenserJ

Reputation: 802

More complicated than a RegExp solution, however it properly handles banana and assassin, where there are two overlapping groups of characters.

This does make use of array.map, array.filter, and array.reduce, which means this exact solution doesn't support <=IE8, however it can be polyfilled quite easily.

function findDuplicateCharacters(input) {
  // Split the string and count the occurrences of each character
  var count = input.split('').reduce(function(countMap, word) {
    countMap[word] = ++countMap[word] || 1;
    return countMap;
  }, {});

  // Get the letters that were found, and filter out any that only appear once.
  var matches = Object.keys(count)
    .filter(function (key) { return (count[key] > 1); })
    // Then map it and create a string with the correct length, filled with that letter.
    .map(function (key) {
      return new Array(count[key] + 1).join(key);
    });

  return matches;
}

var results = ['hello', 'here', 'happiness', 'pupil', 'banana'].map(findDuplicateCharacters);

document.getElementById("results").innerHTML = results.join('<br />');
<div id="results"></div>

Upvotes: 1

deadboy
deadboy

Reputation: 859

var obj = {};
var str = "this is my string";
for (var i = 97; i < 97 + 26; i++) 
  obj[String.fromCharCode(i)] = 0;
for (var i = 0; i < str.length; i++) {
  obj[str.charAt(i).toLowerCase()]++;
}

From there you can say obj["a"] to get the number of occurrences for any particular letter.

Upvotes: 1

Related Questions