Project

General

Profile

Feature #17056

Updated by sawa (Tsuyoshi Sawada) over 3 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 use case of finding file, trying to find the first matching line within a given section in a file. After finding 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 _after_ that line. 

 My workaround for now is to use `with_index`: 

 ```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 in a the more concise way using a feature of `Array#index` that I propose here, which is analogous to `String#index`. can do this with strings, given a starting position. 


 ## Feature parity 

 If the second parameter of `String#index` is present, it specifies the position in the string to begin the search: 

 ```ruby 
 'abcabc'.index('a') # => 0 
 'abcabc'.index('a',2) # => 3 
 ``` 

 I This would expect to also be able to do: 

 ```ruby 
 'abcabc'.chars.index('a') # => 0 
 'abcabc'.chars.index('a', 2) 
 ``` 

 Using such feature, I would be able to do: 

 ```ruby 
 lines.index(sought, section_start_line) 
 ``` 

 This would 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? 

 We can further think of Ideally, we would also add an optional parameter to specify the position to end the search. The following languages 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) 

 Ruby's index arg as well, but `String#index` does not have one, so we could make 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) 
 - ...

Back