A simple loop works well:
var str = "scissors";
var indices = [];
for(var i=0; i<str.length;i++) {
if (str[i] === "s") indices.push(i);
}
Now, you indicate that you want 1,4,5,8. This will give you 0, 3, 4, 7 since indexes are zero-based. So you could add one:
if (str[i] === "s") indices.push(i+1);
and now it will give you your expected result.
A fiddle can be see here.
I don't think looping through the whole is terribly efficient
As far as performance goes, I don't think this is something that you need to be gravely worried about until you start hitting problems.
Here is a jsPerf test comparing various answers. In Safari 5.1, the IndexOf performs the best. In Chrome 19, the for loop is the fastest.

A simple loop works well:
var str = "scissors";
var indices = [];
for(var i=0; i<str.length;i++) {
if (str[i] === "s") indices.push(i);
}
Now, you indicate that you want 1,4,5,8. This will give you 0, 3, 4, 7 since indexes are zero-based. So you could add one:
if (str[i] === "s") indices.push(i+1);
and now it will give you your expected result.
A fiddle can be see here.
I don't think looping through the whole is terribly efficient
As far as performance goes, I don't think this is something that you need to be gravely worried about until you start hitting problems.
Here is a jsPerf test comparing various answers. In Safari 5.1, the IndexOf performs the best. In Chrome 19, the for loop is the fastest.

Using the native String.prototype.indexOf method to most efficiently find each offset.
function locations(substring,string){
var a=[],i=-1;
while((i=string.indexOf(substring,i+1)) >= 0) a.push(i);
return a;
}
console.log(locations("s","scissors"));
//-> [0, 3, 4, 7]
This is a micro-optimization, however. For a simple and terse loop that will be fast enough:
// Produces the indices in reverse order; throw on a .reverse() if you want
for (var a=[],i=str.length;i--;) if (str[i]=="s") a.push(i);
In fact, a native loop is faster on chrome that using indexOf!

javascript - Find the indexs of all occerences a character in a string - Stack Overflow
javascript - Get characters index in string - Stack Overflow
javascript - How to get all indexes of a pattern in a string? - Stack Overflow
arrays - Finding all indexes of a specified word within a string in javascript - Stack Overflow
You can try something like the following code, from this answer:
function getIndicesOf(searchStr, str, caseSensitive) {
var startIndex = 0, searchStrLen = searchStr.length;
var index, indices = [];
if (!caseSensitive) {
str = str.toLowerCase();
searchStr = searchStr.toLowerCase();
}
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
indices.push(index);
startIndex = index + searchStrLen;
}
return indices;
}
For example, if you wanted to find all b's and then write them to the document -
var foo = "foo bar baz bat";
var pos = foo.indexOf("b");
while(pos > -1) {
document.write(pos + "<br />");
pos = foo.indexOf("b", pos+1);
}
Output:
4
8
12
You have to use brackets when accessing a field of an array. Parentheses are for calling functions.
const word = "abracadabra";
const input = ["a", "b", "c"];
for (let i = 0; i< word.length; i++) {
if (input.includes(word[i])) {
console.log(i + word[i]);
}
}
Since your question stated exactly:
give me that character and its position in const word
use RegExp.prototype.exec
const word = "abracadabra";
const input = ["a", "b", "c"];
input.forEach(c => {
const re = new RegExp(c, "g");
let m;
while (m = re.exec(word)) console.log(`${c} found at index ${m.index}`);
});
Another yet nice way to achieve the same is by using Array.prototype.reduce():
const word = "abracadabra";
const input = ["a", "b", "c"];
const res = input.reduce((ob, c) => {
ob[c] = [...word].reduce((a, w, i) => {
if (w === c) a.push(i);
return a;
}, []);
return ob;
}, {});
console.log(res);
which will return an Object, with the character property having an array with all the positions occurrences:
{
"a": [0, 3, 5, 7, 10],
"b": [1, 8],
"c": [4]
}
You can use the RegExp#exec method several times:
var regex = /a/g;
var str = "abcdab";
var result = [];
var match;
while (match = regex.exec(str))
result.push(match.index);
alert(result); // => [0, 4]
Helper function:
function getMatchIndices(regex, str) {
var result = [];
var match;
regex = new RegExp(regex);
while (match = regex.exec(str))
result.push(match.index);
return result;
}
alert(getMatchIndices(/a/g, "abcdab"));
You could use / abuse the replace function:
var result = [];
"abcdab".replace(/(a)/g, function (a, b, index) {
result.push(index);
});
result; // [0, 4]
The arguments to the function are as follows:
function replacer(match, p1, p2, p3, offset, string) {
// p1 is nondigits, p2 digits, and p3 non-alphanumerics
return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString); // abc - 12345 - #$*%
You can use the following code.
let str = 'Testing JavaScript, JavaScript is the Best, JavaScript is Ultimate';
function findAllIndexes(string,word){
let result = [];
let dif = 0;
while(true){
let index = string.indexOf(word);
if(index === -1) break;
else{
result.push(index + dif);
let cur = string.length;
string = string.substring(index + word.length);
dif += cur - string.length;
}
}
return result;
}
console.log(findAllIndexes(str,"JavaScript"));
You can do this using a regular expression.
let word = 'Testing JavaScript, JavaScript is the Best, JavaScript is Ultimate';
var regex = /JavaScript/gi,result,indices=[];
while((result=regex.exec(word)))
{
indices.push(result.index);
}
console.log(indices);
var str = "I learned to play the Ukulele in Lebanon."
var regex = /le/gi, result, indices = [];
while ( (result = regex.exec(str)) ) {
indices.push(result.index);
}
UPDATE
I failed to spot in the original question that the search string needs to be a variable. I've written another version to deal with this case that uses indexOf, so you're back to where you started. As pointed out by Wrikken in the comments, to do this for the general case with regular expressions you would need to escape special regex characters, at which point I think the regex solution becomes more of a headache than it's worth.
function getIndicesOf(searchStr, str, caseSensitive) {
var searchStrLen = searchStr.length;
if (searchStrLen == 0) {
return [];
}
var startIndex = 0, index, indices = [];
if (!caseSensitive) {
str = str.toLowerCase();
searchStr = searchStr.toLowerCase();
}
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
indices.push(index);
startIndex = index + searchStrLen;
}
return indices;
}
var indices = getIndicesOf("le", "I learned to play the Ukulele in Lebanon.");
document.getElementById("output").innerHTML = indices + "";
<div id="output"></div>
Run code snippetEdit code snippet Hide Results Copy to answer Expand
One liner using String.prototype.matchAll (ES2020):
[...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index)
Using your values:
const sourceStr = 'I learned to play the Ukulele in Lebanon.';
const searchStr = 'le';
const indexes = [...sourceStr.matchAll(new RegExp(searchStr, 'gi'))].map(a => a.index);
console.log(indexes); // [2, 25, 27, 33]
If you're worried about doing a spread and a map() in one line, I ran it with a for...of loop for a million iterations (using your strings). The one liner averages 1420ms while the for...of averages 1150ms on my machine. That's not an insignificant difference, but the one liner will work fine if you're only doing a handful of matches.
See matchAll on caniuse
Try something like:
var regexp = /abc/g;
var foo = "abc1, abc2, abc3, zxy, abc4";
var match, matches = [];
while ((match = regexp.exec(foo)) != null) {
matches.push(match.index);
}
console.log(matches);
Here is a working function:
function allIndexOf(str, toSearch) {
var indices = [];
for(var pos = str.indexOf(toSearch); pos !== -1; pos = str.indexOf(toSearch, pos + 1)) {
indices.push(pos);
}
return indices;
}
Use example:
> allIndexOf('dsf dsf kfvkjvcxk dsf', 'dsf');
[0, 4, 18]