improve Enumerable#reverse_each to be efficient
[mruby.git] / mrbgems / mruby-enum-ext / mrblib / enum.rb
blob0ce1d760558ae90d4967dfb89bee0ec7700f7a9a
1 ##
2 # Enumerable
4 module Enumerable
5   ##
6   # call-seq:
7   #    enum.drop(n)               -> array
8   #
9   # Drops first n elements from <i>enum</i>, and returns rest elements
10   # in an array.
11   #
12   #    a = [1, 2, 3, 4, 5, 0]
13   #    a.drop(3)             #=> [4, 5, 0]
15   def drop(n)
16     raise TypeError, "expected Integer for 1st argument" unless n.kind_of? Integer
17     raise ArgumentError, "attempt to drop negative size" if n < 0
19     ary = []
20     self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 }
21     ary
22   end
24   ##
25   # call-seq:
26   #    enum.drop_while {|arr| block }   -> array
27   #
28   # Drops elements up to, but not including, the first element for
29   # which the block returns +nil+ or +false+ and returns an array
30   # containing the remaining elements.
31   #
32   #    a = [1, 2, 3, 4, 5, 0]
33   #    a.drop_while {|i| i < 3 }   #=> [3, 4, 5, 0]
35   def drop_while(&block)
36     ary, state = [], false
37     self.each do |*val|
38       state = true if !state and !block.call(*val)
39       ary << val.__svalue if state
40     end
41     ary
42   end
44   ##
45   # call-seq:
46   #    enum.take(n)               -> array
47   #
48   # Returns first n elements from <i>enum</i>.
49   #
50   #    a = [1, 2, 3, 4, 5, 0]
51   #    a.take(3)             #=> [1, 2, 3]
53   def take(n)
54     raise TypeError, "expected Integer for 1st argument" unless n.kind_of? Integer
55     raise ArgumentError, "attempt to take negative size" if n < 0
57     ary = []
58     self.each do |*val|
59       break if ary.size >= n
60       ary << val.__svalue
61     end
62     ary
63   end