Feature #17056
Updated by TylerRick (Tyler Rick) over 4 years ago
The docs for `String#index` say:
> If the second parameter is present, it specifies the position in the string to begin the search.
So you can do:
```ruby
> 'abcabc'.index('a',2)
#=> 3
'abcabc'.index('a')
#=> 0
```
I would expect to also be able to do:
```ruby
'abcabc'.chars.index('a')
#=> 0
'abcabc'.chars.index('a', 2)
ArgumentError: wrong number of arguments (given 2, expected 0..1)
from (pry):19:in `index'
```
After using this feature on strings, it is surprising to find that it is not available on arrays.
## Use case
One use case I have for this is scanning a file, trying to find the first matching line within a given section. So first I find the line number of the start of the section, and then I want to use that to find the first match _after_ that line.
```ruby
lines = pathname.read.lines
section_start_line = lines.index {|line| line.start_with?(/#* #{section_name}/) }
lines.index(sought, section_start_line)
```
My workaround for now is to use `index.with_index`:
```ruby
lines.index.with_index {|line, i| i > section_start_line && line.include?(sought) }
```
but I'd like to do it the more concise way that I can do this with strings, given a starting position.
## Feature parity
This would also give Ruby better parity with other programming languages that support this, like Python:
```python
>>> list('abcabc')
['a', 'b', 'c', 'a', 'b', 'c']
>>> list('abcabc').index('a')
0
>>> list('abcabc').index('a', 2)
3
```
## End index too?
Ideally, we would also add an optional end index arg as well, but `String#index` does not have one, so we could a separate proposal to add `end` to both methods at the same time.
Other languages that allow specifying both start and end indexes:
- [Python](https://docs.python.org/3/tutorial/datastructures.html)
- [C#](https://docs.microsoft.com/en-us/dotnet/api/system.array.indexof?view=netcore-3.1)
- ...