Module: Tb::ExEnumerator
- Defined in:
- lib/tb/ex_enumerator.rb
Overview
Copyright © 2012 Tanaka Akira <[email protected]>
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Class Method Summary collapse
-
.merge_sorted(*enumerators) ⇒ Object
:call-seq:.
Class Method Details
.merge_sorted(*enumerators) ⇒ Object
:call-seq:
Tb::ExEnumerator.merge_sorted(enumerator1, ...) {|key, enumerator1_or_nil, ...| ... }
iterates over enumerators specified by arguments.
The enumerators should yield an array which first element is a comparable key. The enumerators should be sorted by the key in ascending order.
Tb::Enumerator.merge_sorted iterates keys in all of the enumerators. It yields an array which contains a key and enumerators which has the key. The array contains nil if corresponding enumerator don’t have the key.
The block may or may not use next
method to advance enumerators. Anyway Tb::Enumerator.merge_sorted advance enumerators until peeked key is greater than the yielded key.
If a enumerator has multiple elements with same key, the block can read them using next
method. peek
method should also be used to determine the key of the next element has the current key or not. Be careful to not consume extra elements with different key.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 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 |
# File 'lib/tb/ex_enumerator.rb', line 53 def (Tb::ExEnumerator).merge_sorted(*enumerators) # :yields: [key, enumerator1_or_nil, ...] while true has_min = false min = nil min_enumerators = [] enumerators.each {|kpe| begin key, = kpe.peek rescue StopIteration min_enumerators << nil next end if !has_min has_min = true min = key min_enumerators << kpe else cmp = key <=> min if cmp < 0 min_enumerators.fill(nil) min_enumerators << kpe min = key elsif cmp == 0 min_enumerators << kpe else min_enumerators << nil end end } if !has_min return end yield [min, *min_enumerators] min_enumerators.each {|kpe| next if !kpe while true begin key, = kpe.peek rescue StopIteration break end if (min <=> key) < 0 break end kpe.next end } end end |