Reputation: 9810
I have a string in js and I want to record the index of each instance of the letter X
.
I firstly tried using map
but this just returned undefined
along with the indexes, which I could have used, but would have required an additional function.
Then I used filter
instead but unfortunately this is not returning the index. See example below:
const str = 'Hello there XXXX, how are you?';
let indexes = str.split('').filter((letter, index) => {
if(letter === 'X'){
return index;
}
});
console.log(indexes);
Upvotes: 0
Views: 3457
Reputation: 6299
Array.filter() creates a new array based on the result of the callback. If the return value in each callback is truthy, a new array with all the elements will be returned. If the return value of each callback in falsy, an empty array will be constructed.
So in this condition,
if(letter === 'X'){
return index;
}
the index will be a number > 0 (truthy), so all 'X' will be returned as a new array. If the first character in your input is 'X', the return statement will be 0
which is falsy and that character won't be in the newly constructed array that filter()
returns.
You could use write something like this instead,
const str = 'Hello there XXXX, how are you?';
str.split('')
.map((e, i) => e === 'X' ? {allow: true, index: i} : {allow: false})
.filter(e => e.allow)
.map(e => e.index)
Upvotes: 1
Reputation: 413916
You can do what you want without having to split the string first:
let xes = [];
for (let i = 0; (i = str.indexOf("X", i)) !== -1; xes.push(i++));
That finds each "X" with .indexOf()
, starting from the last position plus 1.
Upvotes: 1
Reputation: 63570
You can use reduce
instead. Here we supply an array as an initial value and push an index to it when the condition is met on an iteration.
const str = 'Hello there XXXX, how are you?';
let indexes = str.split('').reduce((arr, letter, index) => {
if (letter === 'X') arr.push(index);
return arr;
}, []);
console.log(indexes);
Upvotes: 2
Reputation: 2378
I think it would be better to fill indexes array by using forEach
loop:
const str = 'Hello there XXXX, how are you?';
let indexes = [];
str.split('').forEach((letter, index) => {
if(letter === 'X'){
indexes.push(index);
}
});
console.log(indexes);
Upvotes: 2
Reputation: 386746
You could take Array.from
, get every character of the string (as any other iterable) and map the index or -1
for not wanted character. Later filter only wanted indices.
You need two loops for this task, because the first takes the indices and the second filters the intermediate result. Your approach by taking only Array#filter
returns the elements, but not the index of the the element. After filtering, the indices are gone.
const str = 'Hello there XXXX, how are you?';
let indexes = Array.from(str, (c, i) => c === 'X' ? i : -1).filter(i => i !== -1);
console.log(indexes);
Upvotes: 0