我需要计算字符串中某个字符出现的次数。

例如,假设我的字符串包含:

var mainStr = "str1,str2,str3,str4";

我想求出逗号的个数,也就是3个字符。以及按逗号分隔后的单个字符串的计数,也就是4。

我还需要验证每个字符串,即str1或str2或str3或str4不应该超过,比如说,15个字符。


当前回答

我发现在非常大的字符串(例如,长度为1 000 000个字符)中搜索字符的最佳方法是使用replace()方法。

window.count_replace = function (str, schar) {
    return str.length - str.replace(RegExp(schar), '').length;
};

您还可以看到另一个JSPerf套件用于测试该方法以及在字符串中查找字符的其他方法。

其他回答

我相信您会发现下面的解决方案非常短,非常快,能够处理非常长的字符串,能够支持多字符搜索,防错,并能够处理空字符串搜索。

function substring_count(source_str, search_str, index) {
    source_str += "", search_str += "";
    var count = -1, index_inc = Math.max(search_str.length, 1);
    index = (+index || 0) - index_inc;
    do {
        ++count;
        index = source_str.indexOf(search_str, index + index_inc);
    } while (~index);
    return count;
}

使用示例:

console.log(substring_count("Lorem ipsum dollar un sit amet.", "m ")) 函数substring_count(source_str, search_str, index) { Source_str += "", search_str += ""; var count = -1, index_inc = Math.max(search_str. var)长度,1); Index = (+ Index || 0) - index_inc; {做 + +计数; Index = source_str。indexOf(search_str, index + index_inc); } while (~index); 返回计数; }

上面的代码修复了Jakub Wawszczyk的主要性能错误,即使在indexOf说没有匹配之后,代码仍然在寻找匹配,而且他的版本本身也不能工作,因为他忘记给函数输入参数。

我用ramda js的解决方案:

const testString = 'somestringtotest'

const countLetters = R.compose(
  R.map(R.length),
  R.groupBy(R.identity),
  R.split('')
)

countLetters(testString)

链接到REPL。

更新:这可能是简单的,但它不是最快的。参见下面的基准测试。


令人惊讶的是,13年了,这个答案还没有出现。从直觉上看,它应该是最快的:

const s = "The quick brown fox jumps over the lazy dog.";
const oCount = s.length - s.replaceAll('o', '').length;

如果字符串中只有两种字符,那么这样仍然更快:


const s = "001101001";
const oneCount = s.replaceAll('0', '').length;

基准

const { performance } = require('node:perf_hooks');

const ITERATIONS = 10000000;
const TEST_STRING = "The quick brown fox jumps over the lazy dog.";

console.log(ITERATIONS, "iterations");

let sum = 0; // make sure compiler doesn't optimize code out
let start = performance.now();
for (let i = 0; i < ITERATIONS; ++i) {
  sum += TEST_STRING.length - TEST_STRING.replaceAll('o', '').length;
}
let end = performance.now();
console.log("  replaceAll duration", end - start, `(sum ${sum})`);

sum = 0;
start = performance.now();
for (let i = 0; i < ITERATIONS; ++i) {
  sum += TEST_STRING.split('o').length - 1
}
end = performance.now();
console.log("  split duration", end - start, `(sum ${sum})`);
10000 iterations
  replaceAll duration 2.6167500019073486 (sum 40000)
  split duration 2.0777920186519623 (sum 40000)
100000 iterations
  replaceAll duration 17.563208997249603 (sum 400000)
  split duration 8.087624996900558 (sum 400000)
1000000 iterations
  replaceAll duration 128.71587499976158 (sum 4000000)
  split duration 64.15841698646545 (sum 4000000)
10000000 iterations
  replaceAll duration 1223.3415840268135 (sum 40000000)
  split duration 629.1629169881344 (sum 40000000)

我发现在非常大的字符串(例如,长度为1 000 000个字符)中搜索字符的最佳方法是使用replace()方法。

window.count_replace = function (str, schar) {
    return str.length - str.replace(RegExp(schar), '').length;
};

您还可以看到另一个JSPerf套件用于测试该方法以及在字符串中查找字符的其他方法。

var mainStr = “str1,str2,str3,str4”; var splitStr = mainStr.split(“,”).length - 1;减去 1 很重要! alert(splitStr);

分割成一个数组会给我们一些元素,这些元素总是比字符的实例数多1。这可能不是最有效的内存,但如果您的输入总是很小,这是一种直接且易于理解的方法。

如果您需要解析非常大的字符串(大于几百个字符),或者如果这是在处理大量数据的核心循环中,我会推荐不同的策略。