【问题标题】:ES6 / lodash count the number of occurrences of a character in a stringES6 / lodash 统计字符串中某个字符出现的次数
【发布时间】:2018-01-06 09:25:03
【问题描述】:

我想统计一个字符在字符串中出现的次数。

这个堆栈溢出帖子使用 ES5 而不是 ES6 或 Lodash:

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

但是,我想知道是否有更多的 ES6 方式来执行此操作。 Lodash 解决方案也是可以接受的。

【问题讨论】:

  • 不知道你为什么需要这么具体的东西。有几种方法可以做到这一点,使用正则表达式,或使用字符串拆分和长度。 Here 是一个请求此功能的 lodash 线程,以及几种替代方法。我猜你可以使用count=0;for (let ch of string) { if ch === (target) count++;} 之类的东西,但这似乎效率低下。同样,您可以将整个字符串分解成一个数组,但我看不出它的意义。
  • 如果您的目标是速度,您会想要使用其中一种 ES5 解决方案。 ES6 技巧一般都是基于函数式编程的,所以开销更大。
  • 这与linked question 完全相同(它也提供 Lodash 解决方案)。 ES6 中没有任何东西可以改进现有 ES5 的解决方案。

标签: javascript ecmascript-6 lodash


【解决方案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);

【讨论】:

  • 我不确定这是他们想要的输出。此外,生成频率图通常是一个 O(n) 算法,但通过在每次迭代中运行整个匹配,您已经使其成为 O(n^2)。
  • @4castle 仍然需要深入研究时间复杂度算法,今天阅读一些,尽管还会阅读更多内容。除了字符串中每个字符的出现次数外,OP 没有指定预期的输出。您认为预期的输出是什么?由于从角度来看,原始问题缺乏 OP 的特殊性,因此在这里。该方法当然可以更简洁地组合
  • @4castle 你是说OP里的“一个角色”吗?
  • 对。我不确定他们是否只想计算单个特定字符的出现次数,或者是否想计算字符串中每个字符的出现次数。无论哪种方式,算法都应该只需要遍历字符串一次。
【解决方案2】:

单行es6,使用String.prototype.match()

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

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

【讨论】:

    【解决方案3】:

    我不认为它比 RegExp 解决方案更好,但它是 ES6。

    将字符串传播到数组,然后过滤结果以仅获取您想要的字母。结果数组的长度是该字母出现的次数。

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

    【讨论】:

      【解决方案4】:

      这是一个 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>

      【讨论】:

        猜你喜欢
        • 2017-10-09
        • 2010-11-12
        • 2013-12-25
        • 2013-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多