< :前の番号
^ :番号順リスト
> :次の番号
P :前の記事(スレッド移動)
N :次の記事(スレッド移動)
|<:前のスレッド
>|:次のスレッド
^ :返事先
_:自分への返事
>:同じ返事先を持つ記事(前)
<:同じ返事先を持つ記事(後)
---:分割してスレッド表示、再表示
| :分割して(縦)スレッド表示、再表示
~ :スレッドのフレーム消去
.:インデックス
..:インデックスのインデックス
Issue #18262 has been updated by Dan0042 (Daniel DeLorme).
+1
Since a lazy enumerator is produced for both #select and #reject, it would make sense for #partition as well.
----------------------------------------
Feature #18262: Enumerator::Lazy#partition
https://bugs.ruby-lang.org/issues/18262#change-94257
* Author: zverok (Victor Shepelev)
* Status: Open
* Priority: Normal
----------------------------------------
(Part of my set of proposals about making `.lazy` more useful/popular.)
Currently:
```ruby
file = File.open('very-large-file.txt')
lines_with_errors, lines_without_errors = file.lazy.partition { _1.start_with?('E:') }
lines_with_errors.class
# => Array, all file is read by this moment
```
This might be not very practical performance-wise and memory-wise.
I am thinking that maybe returning a pair of lazy enumerators might be a good addition to `Enumerator::Lazy`
Naive prototype:
```ruby
class Enumerator::Lazy
def partition(&block)
buffer1 = []
buffer2 = []
source = self
[
Enumerator.new { |y|
loop do
if buffer1.empty?
begin
item = source.next
if block.call(item)
y.yield(item)
else
buffer2.push(item)
end
rescue StopIteration
break
end
else
y.yield buffer1.shift
end
end
}.lazy,
Enumerator.new { |y|
loop do
if buffer2.empty?
begin
item = source.next
if !block.call(item)
y.yield(item)
else
buffer1.push(item)
end
rescue StopIteration
break
end
else
y.yield buffer2.shift
end
end
}.lazy
]
end
end
```
Testing it:
```ruby
Enumerator.produce(1) { |i| puts "processing #{i}"; i + 1 }.lazy
.take(30)
.partition(&:odd?)
.then { |odd, even|
p odd.first(3), even.first(3)
}
# Prints:
# processing 1
# processing 2
# processing 3
# processing 4
# processing 5
# [1, 3, 5]
# [2, 4, 6]
```
As you might notice by the "processing" log, it only fetched the amount of entries that was required by produced enumerators.
The **drawback** would be―as my prototype implementation shows―the need of internal "buffering" (I don't think it is possible to implement lazy partition without it), but it still might be worth a shot?
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>