I created this function that allows you to declare a string
, then multiple instances of a substring. This uses a hash map to keep track of strings that have already been searched for and upon each call of its returning function will give you the next instance of that substring.
I'm wondering if there's a way to do this without crypto. I have the option of applying the strings as a object property but I didn't want to overload memory with those.
I'm not sure if there's a native JavaScript way to do this, either, so I'm open to suggestions of native code or other libraries that achieve this.
var crypto = require('crypto')
var S = require('underscore.string')
var _ = require('lodash')
/** returns a md5 hash of the content */
function getHash (content) {
var shasum = crypto.createHash('md5')
return shasum.update(content).digest('hex')
}
function multiIndexOf (s) {
var map = []
return function (ss) {
var hash = getHash(ss)
var indexes = indexesOf(s, ss)
var countMap = _.countBy(map)
var instance = countMap[hash] || 0
map.push(hash)
return indexes[instance]
}
}
function indexesOf (s, ss) {
var instances = S.count(s, ss)
return _.chain(instances)
.range()
.reduce(function (indexes, instance) {
var lastIndex = _.last(indexes)
var start = (typeof lastIndex === 'undefined') ? 0 : lastIndex + ss.length
var index = s.indexOf(ss, start)
indexes.push(index)
return indexes
}, [])
.value()
}
var find = multiIndexOf('hello world, hello darling')
console.log(find('hello')) // => 0
console.log(find('hello')) // => 13