diff --git a/src/index.js b/src/index.js index 530fde17..b0257675 100644 --- a/src/index.js +++ b/src/index.js @@ -67,6 +67,7 @@ import tail from './tail' import makeObjectIterable from './makeObjectIterable' import fibonacciSum from './fibonacciSum' import lcm from './lcm' +import occurrences from './occurrences' export { reverseArrayInPlace, @@ -138,4 +139,5 @@ export { makeObjectIterable, fibonacciSum, lcm, + occurrences, } diff --git a/src/occurrences.js b/src/occurrences.js new file mode 100644 index 00000000..d56ec5c1 --- /dev/null +++ b/src/occurrences.js @@ -0,0 +1,35 @@ +/** + * Original Source: https://stackoverflow.com/questions/4009756/how-to-count-string-occurrence-in-string + * + * Function that count occurrences of a substring in a string + * + * @param {String} string The string + * @param {String} subString The sub string to search for + * @param {Boolean} [allowOverlapping] Optional. (Default:false) + */ + +function occurrences(string, subString, allowOverlapping) { + string += '' + subString += '' + if (subString.length <= 0) { + return (string.length + 1) + } + + let n = 0 + let pos = 0 + const step = allowOverlapping ? 1 : subString.length + let flag = true + + while (flag) { + pos = string.indexOf(subString, pos) + if (pos >= 0) { + ++n + pos += step + } else { + flag = false + } + } + return n +} + +export default occurrences diff --git a/test/occurrences.test.js b/test/occurrences.test.js new file mode 100644 index 00000000..bab92049 --- /dev/null +++ b/test/occurrences.test.js @@ -0,0 +1,43 @@ +import test from 'ava' +import { occurrences } from '../src' + +test('empty substring', t => { + t.deepEqual(occurrences('', ''), 1) + t.deepEqual(occurrences('abc', ''), 4) +}) + +test('single occurences', t => { + t.deepEqual(occurrences('foo', 'foo'), 1) + t.deepEqual(occurrences('blahfooblah', 'foo'), 1) + t.deepEqual(occurrences('foo', 'f'), 1) +}) + +test('multiple occurrences', t => { + t.deepEqual(occurrences('foofoofoofoo', 'foo'), 4) + t.deepEqual(occurrences('foofoofoofoo', 'foofoo'), 2) + t.deepEqual(occurrences('blafooblahfooblah', 'foo'), 2) + t.deepEqual(occurrences('foofoofooooofo', 'foo'), 3) +}) + +test('no occurrences', t => { + t.deepEqual(occurrences('', 'foo'), 0) + t.deepEqual(occurrences('abc', 'foo'), 0) + t.deepEqual(occurrences('boo', 'foo'), 0) +}) + +test('overlap', t => { + t.deepEqual(occurrences('', '', true), 1) + t.deepEqual(occurrences('abc', '', true), 4) + t.deepEqual(occurrences('foofoofoofoo', 'foofoo', true), 3) + t.deepEqual(occurrences('blafooblahfooblah', 'foo', true), 2) + t.deepEqual(occurrences('foofoofooooofo', 'foo', true), 3) +}) + +test('overlap no occurrences', t => { + t.deepEqual(occurrences('', 'foo', true), 0); + t.deepEqual(occurrences('abc', 'foo', true), 0); + t.deepEqual(occurrences('boo', 'foo', true), 0); + t.deepEqual(occurrences('fooofooofooofoo', 'foofoo', true), 0); + t.deepEqual(occurrences('blafobooblahfoboblah', 'foo', true), 0); + t.deepEqual(occurrences('fofofofaooooofo', 'foo', true), 0); +}) \ No newline at end of file