Skip to content

Commit

Permalink
make count algorithm more efficient
Browse files Browse the repository at this point in the history
  • Loading branch information
shinnn committed Sep 28, 2018
1 parent 54a9212 commit c7d2839
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ branches:
except: /^v\d/
language: node_js
node_js: node
after_script: node_modules/.bin/nyc report --reporter=text-lcov | npx coveralls
after_script: node_modules/.bin/nyc report | npx coveralls
60 changes: 47 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,64 @@
'use strict';

var arrIndexesOf = require('arr-indexes-of');
var appendType = require('append-type');

/*!
* repetition-ranges | ISC (c) Shinnosuke Watanabe
* https://github.com/shinnn/repetition-ranges
*/

module.exports = function repetitionRanges(arr, value) {
var indexes = arrIndexesOf(arr, value);
if (!Array.isArray(arr)) {
throw new TypeError('Expected an array, but got ' + appendType(arr) + '.');
}

var results = [];
var i = 0;
var start = null;

while (i < indexes.length) {
if (indexes[i] === indexes[i + 1] - 1) {
if (arr.length < 2) {
return results;
}

var i = arr.indexOf(value);

if (i === -1) {
return results;
}

var last = arr.lastIndexOf(value);

if (i === last) {
return results;
}

if (i + 1 === last) {
return [{start: i, end: last}];
}

var start = i++;

do {
if (arr[i] !== value) {
start = null;
continue;
}

if (arr[i + 1] === value) {
if (start === null) {
start = indexes[i];
start = i;
}
} else if (start !== null) {

continue;
}

if (start !== null) {
results.push({
start: start,
end: indexes[i]
end: i
});

start = null;
}

i += 1;
}
start = null;
} while (i++ < last);

return results;
}
59 changes: 46 additions & 13 deletions index.mjs
Original file line number Diff line number Diff line change
@@ -1,28 +1,61 @@
import arrIndexesOf from 'arr-indexes-of';
/*!
* repetition-ranges | ISC (c) Shinnosuke Watanabe
* https://github.com/shinnn/repetition-ranges
*/
import appendType from 'append-type';

export default function repetitionRanges(arr, value) {
var indexes = arrIndexesOf(arr, value);
if (!Array.isArray(arr)) {
throw new TypeError('Expected an array, but got ' + appendType(arr) + '.');
}

var results = [];
var i = 0;
var start = null;

while (i < indexes.length) {
if (indexes[i] === indexes[i + 1] - 1) {
if (arr.length < 2) {
return results;
}

var i = arr.indexOf(value);

if (i === -1) {
return results;
}

var last = arr.lastIndexOf(value);

if (i === last) {
return results;
}

if (i + 1 === last) {
return [{start: i, end: last}];
}

var start = i++;

do {
if (arr[i] !== value) {
start = null;
continue;
}

if (arr[i + 1] === value) {
if (start === null) {
start = indexes[i];
start = i;
}
} else if (start !== null) {

continue;
}

if (start !== null) {
results.push({
start: start,
end: indexes[i]
end: i
});

start = null;
}

i += 1;
}
start = null;
} while (i++ < last);

return results;
}
30 changes: 11 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"elements"
],
"dependencies": {
"arr-indexes-of": "^2.0.0"
"append-type": "^1.0.1"
},
"devDependencies": {
"@shinnn/eslint-config": "^6.7.1",
Expand Down
10 changes: 8 additions & 2 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ test('repetitionRanges()', t => {
t.deepEqual(arr, ['a', 'b', 'b'], 'should not mutate the passed array.');

t.deepEqual(
repetitionRanges([0, 0, '0', 0, 0, 0, Buffer.from('0'), null, undefined], 0),
[{start: 0, end: 1}, {start: 3, end: 5}],
repetitionRanges([0, 0, '0', 0, 0, 0, Buffer.from('0'), null, undefined, 0, 0], 0),
[{start: 0, end: 1}, {start: 3, end: 5}, {start: 9, end: 10}],
'should get multiple positions if exist.'
);

Expand All @@ -32,6 +32,12 @@ test('repetitionRanges()', t => {
'should return an empty array if the search value doesn\'t exist in the array.'
);

t.deepEqual(
repetitionRanges([1, 2, 3], 1),
[],
'should return an empty array if the search value appears only once.'
);

t.deepEqual(
repetitionRanges([], true),
[],
Expand Down

0 comments on commit c7d2839

Please sign in to comment.