Skip to content

Instantly share code, notes, and snippets.

@jimsynz
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jimsynz/cbc5c7556de71038a0ab to your computer and use it in GitHub Desktop.
Save jimsynz/cbc5c7556de71038a0ab to your computer and use it in GitHub Desktop.
Duck punch `skip` into `Enumerable` because it should have it.
module Enumerable
# Duck punch for Enumerable that adds skip() to bypass
# the first `n` elements of the enumerator.
# Use skip/take to retrieve a range of values from an enumerable
# without forcing the values into an array and using [].
#
# This is substantially faster for really big collections, but
# not so much for small ones. ie use at your own risk
# Also, skip provides superficially the same behaviour as drop,
# but it actually doesn't because `drop` returns the remainder
# of the collection as an array, instead of as an enumerable.
#
# Benchmark.bm do |x|
# x.report(" [] 1e3") { (1..1_000).to_a[200..400] }
# x.report("skip 1e3") { (1..1_000).skip(199).take(200) }
# x.report("drop 1e3") { (1..1_000).drop(199).take(200) }
# x.report(" [] 1e9") { (1..1_000_000_000).to_a[200..400] }
# x.report("skip 1e9") { (1..1_000_000_000).skip(199).take(200) }
# x.report("drop 1e9") { (1..1_000_000_000).drop(199).take(200) }
# end
#
# user system total real
# [] 1e3 0.000000 0.000000 0.000000 ( 0.000244)
# skip 1e3 0.000000 0.000000 0.000000 ( 0.000561)
# drop 1e3 0.000000 0.000000 0.000000 ( 0.000037)
# [] 1e9 40.890000 4.830000 45.720000 ( 76.255222)
# skip 1e9 0.010000 0.010000 0.020000 ( 0.000922)
# drop 1e9 29.660000 4.190000 33.850000 ( 36.297854)
#
# ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
def skip n
original = each
Enumerator.new do |yielder|
begin
1.upto(n).each { original.next }
while v = original.next
yielder << v
end
rescue StopIteration
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment