Module: Enumerable
- Defined in:
- lib/upm/core_ext.rb
Instance Method Summary collapse
-
#split_after(matcher = nil, options = {}, &block) ⇒ Object
Split the array into chunks, cutting between the matched element and the next element.
-
#split_at(matcher = nil, options = {}, &block) ⇒ Object
Split this enumerable into chunks, given some boundary condition.
-
#split_before(matcher = nil, options = {}, &block) ⇒ Object
Split the array into chunks, cutting before each matched element.
-
#split_between(&block) ⇒ Object
(also: #cut_between)
Split the array into chunks, cutting between two elements.
Instance Method Details
#split_after(matcher = nil, options = {}, &block) ⇒ Object
Split the array into chunks, cutting between the matched element and the next element.
Example:
[1,2,3,4].split_after{|e| e == 3 } #=> [ [1,2,3], [4] ]
124 125 126 127 128 |
# File 'lib/upm/core_ext.rb', line 124 def split_after(matcher=nil, ={}, &block) [:after] ||= true [:include_boundary] ||= true split_at(matcher, , &block) end |
#split_at(matcher = nil, options = {}, &block) ⇒ Object
Split this enumerable into chunks, given some boundary condition. (Returns an array of arrays.)
Options:
:include_boundary => true #=> include the element that you're splitting at in the results
(default: false)
:after => true #=> split after the matched element (only has an effect when used with :include_boundary)
(default: false)
:once => flase #=> only perform one split (default: false)
Examples:
[1,2,3,4,5].split{ |e| e == 3 }
#=> [ [1,2], [4,5] ]
"hello\n\nthere\n".each_line.split_at("\n").to_a
#=> [ ["hello\n"], ["there\n"] ]
[1,2,3,4,5].split(:include_boundary=>true) { |e| e == 3 }
#=> [ [1,2], [3,4,5] ]
chapters = File.read("ebook.txt").split(/Chapter \d+/, :include_boundary=>true)
#=> [ ["Chapter 1", ...], ["Chapter 2", ...], etc. ]
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/upm/core_ext.rb', line 67 def split_at(matcher=nil, ={}, &block) include_boundary = [:include_boundary] || false if matcher.nil? boundary_test_proc = block else if matcher.is_a? Regexp boundary_test_proc = proc { |element| element =~ matcher } else boundary_test_proc = proc { |element| element == matcher } end end Enumerator.new do |yielder| current_chunk = [] splits = 0 max_splits = [:once] == true ? 1 : [:max_splits] each do |e| if boundary_test_proc.call(e) and (max_splits == nil or splits < max_splits) if current_chunk.empty? and not include_boundary next # hit 2 boundaries in a row... just keep moving, people! end if [:after] # split after boundary current_chunk << e if include_boundary # include the boundary, if necessary yielder << current_chunk # shift everything after the boundary into the resultset current_chunk = [] # start a new result else # split before boundary yielder << current_chunk # shift before the boundary into the resultset current_chunk = [] # start a new result current_chunk << e if include_boundary # include the boundary, if necessary end splits += 1 else current_chunk << e end end yielder << current_chunk if current_chunk.any? end end |
#split_before(matcher = nil, options = {}, &block) ⇒ Object
Split the array into chunks, cutting before each matched element.
Example:
[1,2,3,4].split_before{|e| e == 3 } #=> [ [1,2], [3,4] ]
136 137 138 139 |
# File 'lib/upm/core_ext.rb', line 136 def split_before(matcher=nil, ={}, &block) [:include_boundary] ||= true split_at(matcher, , &block) end |
#split_between(&block) ⇒ Object Also known as: cut_between
Split the array into chunks, cutting between two elements.
Example:
[1,1,2,2].split_between{|a,b| a != b } #=> [ [1,1], [2,2] ]
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/upm/core_ext.rb', line 147 def split_between(&block) Enumerator.new do |yielder| current = [] last = nil each_cons(2) do |a,b| current << a if yield(a,b) yielder << current current = [] end last = b end current << last unless last.nil? yielder << current end end |