Project

General

Profile

Actions

Feature #16441

closed

Enumerable#take_while_after

Added by zverok (Victor Shepelev) over 4 years ago. Updated about 4 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
[ruby-core:96385]

Description

The method is just like #take_while, but also includes the item where condition became true.

Examples of usefulness:

str = <<DOC
prologue
<<
1
2
3
>>
epilogue
DOC

Imagine we want to take everything starting from << to >> in short and clean Ruby. Surprisingly, our best guess would be infamous flip-flop:

str.each_line(chomp: true).filter_map { _1 if _1 == '<<'.._1 == '>>' }
# => ["<<", "1", "2", "3", ">>"]

Trying to achieve this with Enumerator, you almost can express it, but the last line is lost:

str.each_line(chomp: true).drop_while { _1 != '<<' }.take_while { _1 != '>>' }
# => ["<<", "1", "2", "3"]

So, Enumerable leaves us with this (which is harder to read, due to additional .first):

str.each_line(chomp: true).drop_while { _1 != '<<' }.slice_after { _1 == '>>' }.first
# => ["<<", "1", "2", "3", ">>"]

With proposed method:

str.each_line(chomp: true).drop_while { _1 != '<<' }.take_while_after { _1 != '>>' }
# => ["<<", "1", "2", "3", ">>"]

The idea is the same as with flip-flops .. vs ... (sometimes we need to include the last element matching the condition, sometimes don't), and while ... end vs do ... while. Another example (from Enumerator.produce proposal):

require 'strscan'
scanner = StringScanner.new('7+38/6')

Enumerator.produce { scanner.scan(%r{\d+|[-+*/]}) }.take_while { !scanner.eos? }
# => ["7", "+", "38", "/"]

Enumerator.generate { scanner.scan(%r{\d+|[-+*/]}) }.slice_after { scanner.eos? }.first
# => ["7", "+", "38", "/", "6"]

Enumerator.produce { scanner.scan(%r{\d+|[-+*/]}) }.take_while_after { !scanner.eos? }
# => ["7", "+", "38", "/", "6"]

PS: Not sure about the name, suggestions are welcome


Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #16446: Enumerable#take_*, Enumerable#drop_* counterparts with positive conditionsRejectedActions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0