ES6 / lodash 如何统计字符串中某个字符出现的次数?

11

不确定为什么您需要如此具体的东西。有几种方法可以做到这一点,使用正则表达式或使用字符串分割和长度。这里是一个lodash线程,请求此功能以及几种替代方法。我猜您可以使用类似count=0;for (let ch of string) { if ch === (target) count++;}的东西,但那似乎效率低下。同样,您可以将整个字符串拆分成数组,但我看不出有什么意义。 - John C
如果你想追求速度,那么你应该使用ES5解决方案之一。ES6技巧通常基于函数式编程,因此它们具有更多的开销。 - 4castle
2
这是链接问题的完全副本(它还提供了Lodash解决方案)。在ES6中没有任何东西可以改进现有的ES5解决方案。 - Estus Flask
4个回答

21

这里是一个利用 Lodash 的解决方案:

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>

这个解决方案看起来很简洁,没有使用正则表达式,在一次扫描中完成了工作。尽管速度应该相当快,但如果性能真的很关键,最好选择老牌的for循环。

更新:另一个基于Lodash的解决方案:

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>


7

我认为这种方法并不比正则表达式更好,但它是ES6。

将字符串分散成数组,然后筛选结果以仅获取您想要的字母。结果数组的长度是该字母出现的次数。

const str = "aabbccaaaaaaaccc";

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

console.log(result);


2

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

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

console.log(count('abcdefgaaa', 'a'));


1
你可以使用 Array.from()RegExp 构造函数和 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)

如果要仅计算字符出现的次数,您可以使用带有===&&++运算符的for..of循环。

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

let occurrences = 0;

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

console.log(occurrences);


2
我不确定这是否是他们想要的输出。此外,生成频率映射通常是O(n)算法,但您通过在每次迭代中运行整个匹配使其变为了O(n^2)。 - 4castle
@4castle 我还需要深入研究时间复杂度算法,今天已经读了一些,但还需要继续阅读。原帖并没有明确指定期望的输出结果,除了字符串中每个字符出现的次数。你认为期望的输出是什么?由于原始问题缺乏来自OP的要求方面的具体性,因此这里的方法肯定可以更简洁地组成。 - guest271314
@4castle 你的意思是指 OP 中的“一个字符”吗? - guest271314
1
没错。我不确定他们想要计算单个特定字符的出现次数,还是想要计算字符串中每个字符的出现次数。无论哪种方式,算法都只需要对字符串进行一次遍历。 - 4castle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接