From: eregontp@... Date: 2020-09-25T10:11:05+00:00 Subject: [ruby-core:100134] [Ruby master Feature#17056] Array#index: Allow specifying the position to start search as in String#index Issue #17056 has been updated by Eregon (Benoit Daloze). What if a block is given, and one want to use a start index? (for efficiency and not run the block for the first `start` elements). `ary.index(start) { |i| ... }` seems confusing. Probably keyword arguments are better: `ary.index(from: start) { |i| ... }` or `ary.index(start: start) { |i| ... }` Although personally I'm not convinced we need these complications. One can do `'abcabc'.chars[2..].index('a') + 2` instead of `'abcabc'.chars.index('a', 2)`. And the `[2..]` is quite cheap considering that arrays use copy-on-write. It can also be done with `ary = 'abcabc'.chars; (2...ary.size).find { |i| ary[i] == 'a' }`. That's a little bit more complicated, but it's also usable in many more situations than just `index`. I would expect it's fairly rare to need a start offset, so I think there is no need for a shortcut. ---------------------------------------- Feature #17056: Array#index: Allow specifying the position to start search as in String#index https://bugs.ruby-lang.org/issues/17056#change-87705 * Author: TylerRick (Tyler Rick) * Status: Open * Priority: Normal ---------------------------------------- I have a use case of finding the first matching line within a given section in a file. After finding the line number of the start of the section, I want to find the first match 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.with_index {|line, i| i > section_start_line && line.include?(sought) } ``` I'd like to do it in a more concise way using a feature of `Array#index` that I propose here, which is analogous to `String#index`. 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 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 like Python: ```python >>> list('abcabc') ['a', 'b', 'c', 'a', 'b', 'c'] >>> list('abcabc').index('a') 0 >>> list('abcabc').index('a', 2) 3 ``` ## End index We can further think of 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 `String#index` does not have one, so we could make a separate proposal to add `end` to both methods at the same time. -- https://bugs.ruby-lang.org/ Unsubscribe: