After selecting several single-pass algorithms and Guffa regex, I ended up with this:
function findIndexesMultiPass(str,find) { var x, output = {}; for (var i = 0; i < find.length; i++) { output[find[i]] = []; x = 0; while ((x = str.indexOf(find[i], x)) > -1) { output[find[i]].push(x++); } } return output; } var searchString = "abcd abcd abcd"; var searchChars = ['a', 'b']; var result = findIndexesMultiPass(searchString, searchChars);
This turned out to be pretty slow:
function findIndexesOnePass(str,find) { var output = {}; for (var i = 0; i < find.length; i++) { output[find[i]] = []; } for (var i = 0; i < str.length; i++) { var currentChar = str.charAt(i); if (output[currentChar] !== undefined) { output[currentChar].push(i); } } return output; } var searchString = "abcd abcd abcd"; var searchChars = ['a', 'b']; var result = findIndexesOnePass(searchString, searchChars);
Rough times (indices of 3 characters)
Google Chrome (Mac) findIndexesMultiPass: 44ms findIndexesOnePass: 799ms findIndexesRegEx: 95ms Safari findIndexesMultiPass: 48ms findIndexesOnePass: 325ms findIndexesRegEx: 293ms Firefox findIndexesMultiPass: 56ms findIndexesOnePass: 369ms findIndexesRegEx: 786ms
source share