Actions
Feature #12080
openEnumerable#first, Array#last with block
Status:
Open
Assignee:
-
Target version:
-
Description
I propose a new feature: {Enumerable,Array,Range}#first, {Array,Range}#last with block.
If no argument is passed:
-
enum.first { block }
works as the same asenum.find { block }
-
ary.last { block }
works as the same asary.reverse_each.find { block }
If a integer is passed:
-
enum.first(n) { block }
works as the same asenum.lazy.select { block }.first(n)
-
ary.last(n) { block }
works as the same asary.reverse_each.lazy.select { block }.first(n).reverse
Examples:
ary = [1, 2, 3, 4, 5, 6]
ary.first { |i| i.even? } #=> 2
ary.first(2) { |i| i.even? } #=> [2, 4]
ary.last { |i| i.odd? } #=> 5
ary.last(2) { |i| i.odd? } #=> [3, 5]
Currently these methods just ignore given blocks.
ary.first { |i| i > 3 } #=> 1
I sometimes write such code:
ary = ["DEBUG: a", "WARN: b", ..., "WARN: y", "DEBUG: z"] # assume a large Array
ary.reverse_each.lazy.reject { |line| line.include?("DEBUG") }.first(10).reverse #=> returns last 10 non-debug logs
But this is redundant and not intuitive. In this case, I just want the last 10 logs which is not debug message in the original order.
With the new Array#last, I can refactor it:
ary.last(10) { |line| !line.include?("DEBUG") }
I think this represents what I want to do much more clearly.
Files
Actions
Like0
Like0Like0