Подсчитайте количество вхождений символа в строку в Javascript - PullRequest
435 голосов
/ 19 мая 2009

Мне нужно посчитать количество вхождений символа в строку.

Например, предположим, что моя строка содержит:

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

Я хочу найти число запятых , символа, которое равно 3. И количество отдельных строк после разбиения по запятой, которое равно 4.

Мне также нужно проверить, что каждая из строк, т.е. str1 или str2 или str3 или str4, не должна превышать, скажем, 15 символов.

Ответы [ 30 ]

3 голосов
/ 12 февраля 2014

Я работал над небольшим проектом, для которого требовался счетчик подстрок. Поиск неправильных фраз не дал мне никаких результатов, однако после написания собственной реализации я наткнулся на этот вопрос. Во всяком случае, вот мой путь, он, вероятно, медленнее, чем большинство здесь, но может быть полезным для кого-то:

function count_letters() {
var counter = 0;

for (var i = 0; i < input.length; i++) {
    var index_of_sub = input.indexOf(input_letter, i);

    if (index_of_sub > -1) {
        counter++;
        i = index_of_sub;
    }
}

http://jsfiddle.net/5ZzHt/1/

Пожалуйста, дайте мне знать, если вы обнаружите, что эта реализация не работает или не соответствует некоторым стандартам! :)

UPDATE Вы можете заменить:

    for (var i = 0; i < input.length; i++) {

С:

for (var i = 0, input_length = input.length; i < input_length; i++) {

Интересно почитать, обсуждая вышесказанное: http://www.erichynds.com/blog/javascript-length-property-is-a-stored-value

3 голосов
/ 09 января 2017

Самый простой способ, который я узнал ...

ПРИМЕР-

str = 'mississippi';

function find_occurences(str, char_to_count){
    return str.split(char_to_count).length - 1;
}

find_occurences(str, 'i') //outputs 4
2 голосов
/ 23 августа 2018

Вы также можете rest вашей строки и работать с ней как с массивом элементов, используя

const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].filter(l => l === ',').length;

console.log(commas);

или

const mainStr = 'str1,str2,str3,str4';
const commas = [...mainStr].reduce((a, c) => c === ',' ? ++a : a, 0);

console.log(commas);
2 голосов
/ 06 апреля 2017

Если вы используете lodash, метод _. CountBy сделает это:

_.countBy("abcda")['a'] //2

Этот метод также работает с массивом:

_.countBy(['ab', 'cd', 'ab'])['ab'] //2
1 голос
/ 24 июля 2018

А есть:

function character_count(string, char, ptr = 0, count = 0) {
    while (ptr = string.indexOf(char, ptr) + 1) {count ++}
    return count
}

Работает и с целыми числами!

1 голос
/ 19 мая 2009

Следующее использует регулярное выражение для проверки длины. testex гарантирует, что у вас нет 16 или более последовательных символов без запятой. Если он проходит тест, он продолжает разделять строку. подсчет запятых так же прост, как подсчет токенов минус один.

var mainStr = "str1,str2,str3,str4";
var testregex = /([^,]{16,})/g;
if (testregex.test(mainStr)) {
  alert("values must be separated by commas and each may not exceed 15 characters");
} else {
  var strs = mainStr.split(',');
  alert("mainStr contains " + strs.length + " substrings separated by commas.");
  alert("mainStr contains " + (strs.length-1) + " commas.");
}
1 голос
/ 24 мая 2016

А как насчет string.split (требуемый характер) .length-1

Пример:

var str = "привет как жизнь"; var len = str.split ("h"). length-1; даст счет 2 для символа "h" в приведенной выше строке;

1 голос
/ 20 сентября 2017

Я только что сделал очень быстрый и грязный тест на repl.it с использованием Node v7.4. Для одного символа стандарт для цикла самый быстрый:

Какой-то код :

// winner!
function charCount1(s, c) {
    let count = 0;
    c = c.charAt(0); // we save some time here
    for(let i = 0; i < s.length; ++i) {
        if(c === s.charAt(i)) {
            ++count;
        }
    }
    return count;
}

function charCount2(s, c) {
    return (s.match(new RegExp(c[0], 'g')) || []).length;
}

function charCount3(s, c) {
    let count = 0;
    for(ch of s) {
        if(c === ch) {
            ++count;
        }
    }
    return count;
}

function perfIt() {
    const s = 'Hello, World!';
    const c = 'o';

    console.time('charCount1');
    for(let i = 0; i < 10000; i++) {
        charCount1(s, c);
    }
    console.timeEnd('charCount1');

    console.time('charCount2');
    for(let i = 0; i < 10000; i++) {
        charCount2(s, c);
    }
    console.timeEnd('charCount2');

    console.time('charCount3');
    for(let i = 0; i < 10000; i++) {
        charCount2(s, c);
    }
    console.timeEnd('charCount3');
}

Результаты нескольких прогонов :

 perfIt()
charCount1: 3.843ms
charCount2: 11.614ms
charCount3: 11.470ms
=> undefined
   perfIt()
charCount1: 3.006ms
charCount2: 8.193ms
charCount3: 7.941ms
=> undefined
   perfIt()
charCount1: 2.539ms
charCount2: 7.496ms
charCount3: 7.601ms
=> undefined
   perfIt()
charCount1: 2.654ms
charCount2: 7.540ms
charCount3: 7.424ms
=> undefined
   perfIt()
charCount1: 2.950ms
charCount2: 9.445ms
charCount3: 8.589ms
1 голос
/ 12 апреля 2017

Вот один почти такой же быстрый, как методы split и replace, которые чуть-чуть быстрее, чем метод регулярных выражений (в chrome).

var num = 0;
for (ch of "str1,str2,str3,str4")
{
    if (ch === ',') num++;
}
1 голос
/ 22 февраля 2013
s = 'dir/dir/dir/dir/'
for(i=l=0;i<s.length;i++)
if(s[i] == '/')
l++
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...