11

I want to count the number of occurrences of a character in a string.

This stack overflow post does that using ES5 but not ES6 or Lodash:

Count the number of occurrences of a character in a string in Javascript

However, I want to know if there is a more ES6 way of doing this. Lodash solutions are also acceptable.

halfer
  • 19,824
  • 17
  • 99
  • 186
danday74
  • 52,471
  • 49
  • 232
  • 283
  • Not sure why you need something so specific. There are several ways to do this, using Regular Expressions, or using String Split & Length. [Here](https://github.com/lodash/lodash/issues/702) is a lodash thread requesting this funcitonality, along with several alternative methods. I guess you could use something like `count=0;for (let ch of string) { if ch === (target) count++;}` but that seems inefficient. Similarly you could break the entire string out into an array, but I don't see the point of it. – John C Jul 30 '17 at 22:13
  • If your goal is speed, you'll want to use one of those ES5 solutions. ES6 tricks are generally based on functional programming, so they have more overhead. – 4castle Jul 30 '17 at 22:17
  • 2
    This is exact duplicate of [linked question](https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript) (it provides Lodash solutions too). There's nothing in ES6 that would improve a solution over existing ES5 ones. – Estus Flask Jul 30 '17 at 23:27

4 Answers4

21

And here's a lodash solution:

const count = (str, ch) => _.countBy(str)[ch] || 0;

console.log(count("abcadea", "a"));
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

The solution looks compact, does not use regular expressions and still does the job in a single scan. It must be quite fast, though if the performance is really crucial, better opt for good old for loop.

Update: Another lodash-based solution:

const count = (str, ch) => _.sumBy(str, x => x === ch)

console.log(count("abcadea", "a"));
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Sergey Karavaev
  • 1,721
  • 14
  • 16
7

I don't think that it's better than the RegExp solutions, but it's ES6.

Spread the string to and array, and filter the result to get only the letter that you want. The length of the resulting array is the number off occurrences of that letter.

const str = "aabbccaaaaaaaccc";

const result = [...str].filter(l => l === 'c').length;

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
2

Single line es6, uses String.prototype.match()

const count = (str, ch) => (str.match(new RegExp(ch, 'g')) || []).length;

console.log(count('abcdefgaaa', 'a'));
Lucas Astrada
  • 52
  • 1
  • 6
Shane
  • 3,049
  • 1
  • 17
  • 18
1

You can use Array.from(), RegExp constructor and String.prototype.match()

const str = "abcabc";

const occurences = Array.from(str, (s, index) => 
                     ({[s]:str.match(new RegExp(s, "g")).length, index}));

console.log(occurences)

If requirement is to only count the occurrences of

a character

you can use for..of loop with ===, && and ++ operators

const [str, char] = ["abc abc", " "];

let occurrences = 0;

for (const s of str) s === char && ++occurrences; // match space character

console.log(occurrences);
guest271314
  • 1
  • 15
  • 104
  • 177
  • 2
    I'm not sure this is the output they desire. Also, generating a frequency map is usually an O(n) algorithm, but you've made it O(n^2) by running the whole match on every iteration. – 4castle Jul 30 '17 at 22:30
  • @4castle Still have to dive into time complexity algorithms, read some today, though will read more still. OP does not specify what the expected output is other than the number of occurrences of each character in the string. What do you perceive as being expected output? As the speficity from OP is lacking at original Question as to requirement from perspective, here. The approach can certainly be more tersely composed – guest271314 Jul 30 '17 at 22:32
  • @4castle Do you mean _"a character"_ at OP? – guest271314 Jul 30 '17 at 22:34
  • 1
    Right. I'm not sure if they want to count the occurrences of only a single specific character, or if they want to count the occurrences of each character in the string. Either way, the algorithm should only require one pass over the string. – 4castle Jul 30 '17 at 22:36