enumerable_lz 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ChangeLog +6 -0
- data/LICENSE.txt +1 -1
- data/README.md +26 -9
- data/lib/enumerable_lz.rb +42 -2
- data/lib/enumerable_lz/enumerable_ex.rb +50 -8
- data/lib/enumerable_lz/filter.rb +68 -17
- data/lib/enumerable_lz/filter_18.rb +82 -59
- data/lib/enumerable_lz/filter_mrb.rb +37 -14
- data/lib/enumerable_lz/transform.rb +55 -6
- data/lib/enumerable_lz/transform_18.rb +66 -37
- data/lib/enumerable_lz/transform_mrb.rb +32 -5
- data/test/test_filter.rb +31 -10
- data/test/test_transform.rb +24 -2
- metadata +28 -34
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8ad8aeb48998541b0d13a8e20a63aa5d2b6af5ba
|
4
|
+
data.tar.gz: 7f66a110548e37e864bee992327c67ad36580dd4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b7847ff329ce9a00831d66525d7dc5f91fadbe4f33a3a249dcc1cea959eaef37795ab0648e127be80b26ae1a3a83d913a304aa9670b2f76d7269b379a5f9fcbe
|
7
|
+
data.tar.gz: 5511760da227ab917f450a4c9c2af7475d5e88923a374de2d8b1a780edb909fcc1b30b81d9b3c79f5c560e881c22c9a831a4ac900c80f4e1f49487ace01aa745
|
data/ChangeLog
CHANGED
@@ -14,3 +14,9 @@
|
|
14
14
|
|
15
15
|
* Improve performance much more
|
16
16
|
|
17
|
+
== 0.1.5 / 2014-01-08
|
18
|
+
|
19
|
+
* Add `filter.with_index` and `transform.with_index` feature
|
20
|
+
* Add `filter.with_initializer` feature (and obsolete `filter_with_initproc` method)
|
21
|
+
* Add support for Ruby 2.0.0/2.1.0
|
22
|
+
* Improve performance
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License
|
2
2
|
|
3
|
-
Copyright (c) 2011 GOTOH Shunsuke (@antimon2)
|
3
|
+
Copyright (c) 2011,2014 GOTOH Shunsuke (@antimon2)
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -9,17 +9,32 @@ Also it provides lazy equivalents of some methods in `Enumerable`.
|
|
9
9
|
When require 'enumerable_lz', these lazy methods are provided:
|
10
10
|
|
11
11
|
* `Enumerable#filter`
|
12
|
-
* `Enumerable#filter_with_initproc`
|
13
12
|
* `Enumerable#transform`
|
14
13
|
|
15
|
-
|
14
|
+
And some method-chains are provided:
|
15
|
+
|
16
|
+
* `Enumerable#filter.with_index`
|
17
|
+
* `Enumerable#filter.with_initializer`
|
18
|
+
* `Enumerable#transform.with_index`
|
19
|
+
|
20
|
+
For example (in Ruby 1.9.x or greater):
|
16
21
|
|
17
22
|
require 'enumerable_lz'
|
18
23
|
require 'prime'
|
19
|
-
|
24
|
+
|
20
25
|
(1..Float::INFINITY).transform{|n|n**2+1}.filter{|m|m.prime?}.take(100)
|
21
26
|
# => [2, 5, ... , 682277, 739601] for a few msec.
|
22
27
|
|
28
|
+
Prime.filter.with_index{|q,i|i.odd?}.take(10)
|
29
|
+
# => [3, 7, 13, 19, 29, 37, 43, 53, 61, 71]
|
30
|
+
|
31
|
+
Prime.transform.with_index{|q,i|[q,i]}.take(10)
|
32
|
+
# => [[2, 0], [3, 1], [5, 2], [7, 3], [11, 4], [13, 5], [17, 6], [19, 7], [23, 8], [29, 9]]
|
33
|
+
|
34
|
+
# especially, when calling transform.with_index without a block
|
35
|
+
Prime.transform.with_index.take(10)
|
36
|
+
# => [[2, 0], [3, 1], [5, 2], [7, 3], [11, 4], [13, 5], [17, 6], [19, 7], [23, 8], [29, 9]]
|
37
|
+
|
23
38
|
|
24
39
|
## Expanded Usage
|
25
40
|
|
@@ -37,7 +52,7 @@ When require 'enumerable_lz/enumerable_ex', some lazy methods equivalents to ori
|
|
37
52
|
* `Enumerable#take_while_lz`
|
38
53
|
|
39
54
|
|
40
|
-
For example (in Ruby 1.9.x):
|
55
|
+
For example (in Ruby 1.9.x or greater):
|
41
56
|
|
42
57
|
require 'enumerable_lz'
|
43
58
|
require 'enumerable_lz/enumerable_ex'
|
@@ -51,10 +66,12 @@ These expanded methods are inplemented with fundamental filter and transformatio
|
|
51
66
|
|
52
67
|
## Supported Rubies
|
53
68
|
|
54
|
-
* Ruby 1.
|
55
|
-
* Ruby
|
56
|
-
*
|
57
|
-
*
|
69
|
+
* Ruby 2.1.0 (testing 2.1.0-p0)
|
70
|
+
* Ruby 2.0.0 (testing 2.0.0-p247)
|
71
|
+
* Ruby 1.9.x (testing 1.9.3-p448)
|
72
|
+
* Ruby 1.8.7 (testing 1.8.7-p358)
|
73
|
+
* JRuby (testing 1.7.2)
|
74
|
+
* MacRuby (testing 0.12)
|
58
75
|
|
59
76
|
## Installation
|
60
77
|
|
@@ -64,6 +81,6 @@ These expanded methods are inplemented with fundamental filter and transformatio
|
|
64
81
|
## License
|
65
82
|
|
66
83
|
The MIT License
|
67
|
-
Copyright (c) 2011 GOTOH Shunsuke (@antimon2)
|
84
|
+
Copyright (c) 2011, 2014 GOTOH Shunsuke (@antimon2)
|
68
85
|
|
69
86
|
Please see [LICENSE.txt](LICENSE.txt) for details.
|
data/lib/enumerable_lz.rb
CHANGED
@@ -11,8 +11,48 @@ else
|
|
11
11
|
require File.dirname(__FILE__)+'/enumerable_lz/transform_18'
|
12
12
|
end
|
13
13
|
|
14
|
+
# add {#filter} and {#transform} methods.
|
14
15
|
module Enumerable
|
16
|
+
# @!group Fundamental Method Summary
|
17
|
+
|
18
|
+
# Filter by pattern or block
|
19
|
+
# @yield [el]
|
20
|
+
# @overload filter(&block)
|
21
|
+
# filter by block
|
22
|
+
# @yield [el] filterring block.
|
23
|
+
# @yieldparam el each element of original Enumerable
|
24
|
+
# @yieldreturn [Boolean]
|
25
|
+
# @return [Enumerator::Filter]
|
26
|
+
# @overload filter(pattern)
|
27
|
+
# filter by pattern
|
28
|
+
# @param [#===] pattern filterring pattern. (uses === method)
|
29
|
+
# @return [Enumerator::Filter]
|
30
|
+
# @return [Enumerator::Filter]
|
31
|
+
def filter pattern = nil, &block
|
32
|
+
Enumerator::Filter.new self, pattern||block
|
33
|
+
end
|
34
|
+
|
35
|
+
# @yield [el]
|
36
|
+
# @deprecated Use filter.with_initializer instead of this method
|
37
|
+
# @see Enumerator::Filter#with_initializer
|
38
|
+
# @return [Enumerator::Filter]
|
39
|
+
def filter_with_initproc init_proc, pattern = nil, &block
|
40
|
+
filter.with_initializer init_proc, pattern = nil, &block
|
41
|
+
end
|
42
|
+
|
43
|
+
# Transform by block
|
44
|
+
# @yield [el] transform block.
|
45
|
+
# @yieldparam el each element of original Enumerable
|
46
|
+
# @yieldreturn [Object]
|
47
|
+
# @return [Enumerator::Transform]
|
48
|
+
def transform &block
|
49
|
+
Enumerator::Transform.new self, &block
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!endgroup
|
53
|
+
|
54
|
+
# @private
|
15
55
|
module EnumerableLz
|
16
|
-
VERSION = "0.1.
|
56
|
+
VERSION = "0.1.5"
|
17
57
|
end
|
18
|
-
end
|
58
|
+
end
|
@@ -1,49 +1,91 @@
|
|
1
1
|
require File.expand_path('..', __FILE__)
|
2
2
|
|
3
3
|
module Enumerable
|
4
|
+
# @!group Expanded Method Summary
|
5
|
+
|
6
|
+
# lazy equivalent of `Enumerable#select`
|
7
|
+
# @yield [el]
|
8
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
9
|
+
# @return [Enumerator::Filter]
|
4
10
|
def select_lz &block
|
5
11
|
filter &block
|
6
12
|
end
|
7
|
-
|
8
13
|
alias :find_all_lz :select_lz
|
9
14
|
|
15
|
+
# lazy equivalent of `Enumerable#reject`
|
16
|
+
# @yield [el]
|
17
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
18
|
+
# @return [Enumerator::Filter]
|
10
19
|
def reject_lz &block
|
11
20
|
filter {|e|!block.call(e)}
|
12
21
|
end
|
13
22
|
|
23
|
+
# lazy equivalent of `Enumerable#grep`
|
24
|
+
# @yield [el]
|
25
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
26
|
+
# @overload grep_lz(pattern)
|
27
|
+
# @return [Enumerator::Filter]
|
28
|
+
# @overload grep_lz(pattern, &block)
|
29
|
+
# @yield [el]
|
30
|
+
# @return [Enumerator::Transform]
|
31
|
+
# @return [Enumerator::Filter, Enumerator::Transform]
|
14
32
|
def grep_lz pattern, &block
|
15
33
|
enum = filter pattern
|
16
34
|
block_given? ? enum.transform(&block) : enum
|
17
35
|
end
|
18
36
|
|
19
|
-
|
37
|
+
# @!method map_lz(&block)
|
38
|
+
# lazy equivalent of `Enumerable#map`
|
39
|
+
# @yield [el]
|
40
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
41
|
+
# @return [Enumerator::Transform]
|
42
|
+
self.__send__(:alias_method, :map_lz, :transform)
|
20
43
|
alias :collect_lz :map_lz
|
21
44
|
|
45
|
+
# lazy equivalent of `Enumerable#drop`
|
46
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
47
|
+
# @return [Enumerator::Filter]
|
22
48
|
def drop_lz n
|
23
49
|
raise ArgumentError, "attempt to take negative size" if n < 0
|
24
50
|
# each_with_index.filter{|el,idx|idx >= n}.transform{|el,idx|el}
|
25
|
-
cnt = 0
|
26
|
-
filter_with_initproc(Proc.new{cnt=0}) {|el| (cnt+=1) > n}
|
51
|
+
# cnt = 0
|
52
|
+
# filter_with_initproc(Proc.new{cnt=0}) {|el| (cnt+=1) > n}
|
53
|
+
filter.with_index {|el, i| i >= n}
|
27
54
|
end
|
28
55
|
|
56
|
+
# lazy equivalent of `Enumerable#drop_while`
|
57
|
+
# @yield [el]
|
58
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
59
|
+
# @return [Enumerator::Filter]
|
29
60
|
def drop_while_lz &block
|
30
61
|
return self if !block_given?
|
31
62
|
flg = false
|
32
|
-
filter_with_initproc(Proc.new{flg=false}) {|el|flg || (!block.call(el) ? flg = true : false)}
|
63
|
+
# filter_with_initproc(Proc.new{flg=false}) {|el|flg || (!block.call(el) ? flg = true : false)}
|
64
|
+
filter.with_initializer(Proc.new{flg=false}) {|el|flg || (!block.call(el) ? flg = true : false)}
|
33
65
|
end
|
34
66
|
|
67
|
+
# lazy equivalent of `Enumerable#take`
|
68
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
69
|
+
# @return [Enumerator::Filter]
|
35
70
|
def take_lz n
|
36
71
|
raise ArgumentError, "attempt to take negative size" if n < 0
|
37
72
|
# each_with_index.filter{|el,idx|throw :do_break if idx >= n;true}.transform{|el,idx|el}
|
38
|
-
cnt = 0
|
39
|
-
filter_with_initproc(Proc.new{cnt=0}) {|el| throw :do_break if (cnt+=1) > n;true}
|
73
|
+
# cnt = 0
|
74
|
+
# filter_with_initproc(Proc.new{cnt=0}) {|el| throw :do_break if (cnt+=1) > n;true}
|
75
|
+
filter.with_index {|el, i| throw :do_break if i >= n; true}
|
40
76
|
end
|
41
77
|
|
78
|
+
# lazy equivalent of `Enumerable#take_while`
|
79
|
+
# @yield [el]
|
80
|
+
# @note available only requiring "enumerable_lz/enumerable_ex"
|
81
|
+
# @return [Enumerator::Filter]
|
42
82
|
def take_while_lz &block
|
43
83
|
return self if !block_given?
|
44
|
-
filter {|el|throw :do_break unless block.call(el);true}
|
84
|
+
filter {|el|throw :do_break unless block.call(el); true}
|
45
85
|
end
|
46
86
|
|
87
|
+
# @!endgroup
|
88
|
+
|
47
89
|
# def zip_lz *lists
|
48
90
|
# enums = lists.map{|list|list.each rescue [].each}
|
49
91
|
# Enumerator.new do |y|
|
data/lib/enumerable_lz/filter.rb
CHANGED
@@ -1,21 +1,14 @@
|
|
1
|
-
# for Ruby1.9.x except for MacRuby
|
2
|
-
module Enumerable
|
3
|
-
def filter pattern = nil, &block
|
4
|
-
Filter.new self, pattern||block
|
5
|
-
end
|
6
|
-
|
7
|
-
def filter_with_initproc init_proc, pattern = nil, &block
|
8
|
-
Filter.new self, init_proc, pattern||block
|
9
|
-
end
|
1
|
+
# -- for Ruby1.9.x except for MacRuby
|
10
2
|
|
3
|
+
# add [Filter] and [Transform] classes.
|
4
|
+
class Enumerator
|
5
|
+
# Lazy Filterring Enumerator
|
11
6
|
class Filter < Enumerator
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
# @param [Enumerable] obj an Enumerable.
|
8
|
+
# @param [#===] the_filter filterring pattern or proc.
|
9
|
+
def initialize obj, the_filter=nil
|
15
10
|
@org_enum = obj
|
16
|
-
@init_block = init_block unless init_block.nil?
|
17
11
|
super() do |y|
|
18
|
-
@init_block.call unless @init_block.nil?
|
19
12
|
compiled_filter = @filter.nil? ? Proc.new{true} : lambda{|f|
|
20
13
|
break f[0] if f.size==1
|
21
14
|
codes = f.size.times.map do |idx|
|
@@ -32,6 +25,9 @@ module Enumerable
|
|
32
25
|
filter! the_filter if the_filter
|
33
26
|
end
|
34
27
|
|
28
|
+
# Apply filter pattern/block and return self. (bang method of filter)
|
29
|
+
# @yield [el]
|
30
|
+
# @return [Filter] self
|
35
31
|
def filter! pattern=nil, &block
|
36
32
|
@filter||=[]
|
37
33
|
if pattern.is_a? Array
|
@@ -42,9 +38,15 @@ module Enumerable
|
|
42
38
|
self
|
43
39
|
end
|
44
40
|
|
45
|
-
#[override]
|
41
|
+
# [override] for performance
|
42
|
+
# @yield [el]
|
43
|
+
# @overload filter(&block)
|
44
|
+
# @yield [el]
|
45
|
+
# @overload filter(pattern)
|
46
|
+
# @param [#===] pattern
|
47
|
+
# @see Enumerable#filter Enumerable#filter
|
48
|
+
# @return [Filter]
|
46
49
|
def filter pattern=nil, &block
|
47
|
-
return super unless @init_block.nil?
|
48
50
|
# clone.filter! pattern, &block
|
49
51
|
patterns = @filter.nil? ? [] : @filter.clone
|
50
52
|
if pattern.is_a? Array
|
@@ -55,6 +57,33 @@ module Enumerable
|
|
55
57
|
Filter.new @org_enum, patterns
|
56
58
|
end
|
57
59
|
|
60
|
+
# @overload with_initializer(init_proc, &block)
|
61
|
+
# filter by block with initializer proc.
|
62
|
+
# @param [#call] init_proc initializer proc. (uses .call method)
|
63
|
+
# @yield filterring block.
|
64
|
+
# @return [Filter]
|
65
|
+
# @overload with_initializer(init_proc, pattern)
|
66
|
+
# filter by pattern with initializer proc.
|
67
|
+
# @param [#call] init_proc initializer proc. (uses .call method)
|
68
|
+
# @param [#===] pattern filterring pattern. (uses === method)
|
69
|
+
# @return [Filter]
|
70
|
+
# @return [Filter]
|
71
|
+
def with_initializer init_proc, pattern = nil, &block
|
72
|
+
src_enum = @filter.nil? ? @org_enum : self
|
73
|
+
FilterWithInitializer.new src_enum, init_proc, pattern||block
|
74
|
+
end
|
75
|
+
|
76
|
+
# @param [Numeric] offset offset.
|
77
|
+
# @yield [el, i]
|
78
|
+
# @return [Filter]
|
79
|
+
def with_index offset=0, &block
|
80
|
+
raise ArgumentError, "tried to call filter.with_index without a block" unless block_given?
|
81
|
+
i = offset - 1
|
82
|
+
with_initializer(Proc.new{i = offset - 1}) do |el|
|
83
|
+
block.call(el, i += 1)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
58
87
|
private
|
59
88
|
def conv_proc pattern
|
60
89
|
case pattern
|
@@ -65,9 +94,31 @@ module Enumerable
|
|
65
94
|
end
|
66
95
|
end
|
67
96
|
end
|
97
|
+
|
98
|
+
# @api private
|
99
|
+
class FilterWithInitializer < Filter
|
100
|
+
def initialize obj, init_block, the_filter = nil
|
101
|
+
super obj, the_filter
|
102
|
+
@initializer = init_block
|
103
|
+
end
|
104
|
+
|
105
|
+
def each &block
|
106
|
+
return self unless block_given?
|
107
|
+
@initializer.call
|
108
|
+
super &block
|
109
|
+
end
|
110
|
+
|
111
|
+
# @see Enumerable#filter Enumerable#filter
|
112
|
+
# @return [Filter]
|
113
|
+
def filter pattern=nil, &block
|
114
|
+
Filter.new self, pattern||block
|
115
|
+
end
|
116
|
+
end
|
117
|
+
private_constant :FilterWithInitializer if self.respond_to? :private_constant
|
68
118
|
end
|
69
|
-
#against the Bug on JRuby <1.6.2
|
119
|
+
# against the Bug on JRuby < 1.6.2
|
70
120
|
if !(Proc.new{true}===true)
|
121
|
+
# @private
|
71
122
|
class Proc
|
72
123
|
alias :=== :call
|
73
124
|
end
|
@@ -1,76 +1,99 @@
|
|
1
1
|
# for Ruby1.8.7
|
2
|
+
|
2
3
|
module Enumerable
|
3
|
-
|
4
|
-
Filter
|
5
|
-
|
4
|
+
class Enumerator
|
5
|
+
class Filter < Enumerator
|
6
|
+
def initialize obj, the_filter=nil
|
7
|
+
filter! the_filter if the_filter
|
8
|
+
@org_enum = obj
|
9
|
+
end
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
11
|
+
def each &block
|
12
|
+
return self unless block_given?
|
13
|
+
# compiled_filter = (@filter||[Proc.new{true}]).inject do |r,f|
|
14
|
+
# Proc.new{|el| r[el] && f[el]}
|
15
|
+
# end
|
16
|
+
compiled_filter = @filter.nil? ? Proc.new{true} : lambda{|f|
|
17
|
+
break f[0] if f.size==1
|
18
|
+
codes = f.size.times.map do |idx|
|
19
|
+
"f[#{idx}][el]"
|
20
|
+
end
|
21
|
+
eval "Proc.new{|el|"+codes.join(" && ")+"}"
|
22
|
+
}.call(@filter)
|
23
|
+
catch :do_break do
|
24
|
+
@org_enum.each do |el|
|
25
|
+
block.call(el) if compiled_filter[el]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
10
30
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
31
|
+
def filter! pattern=nil, &block
|
32
|
+
@filter||=[]
|
33
|
+
if pattern.is_a? Array
|
34
|
+
pattern.each{|el| @filter << conv_proc(el)}
|
35
|
+
else
|
36
|
+
@filter << conv_proc(pattern || block)
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
19
40
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
codes = f.size.times.map do |idx|
|
29
|
-
"f[#{idx}][el]"
|
41
|
+
#[override]
|
42
|
+
def filter pattern=nil, &block
|
43
|
+
# clone.filter! pattern, &block
|
44
|
+
patterns = @filter.nil? ? [] : @filter.clone
|
45
|
+
if pattern.is_a? Array
|
46
|
+
patterns.push(*pattern)
|
47
|
+
else
|
48
|
+
patterns << (pattern || block)
|
30
49
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
50
|
+
Filter.new @org_enum, patterns
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_initializer init_proc, pattern = nil, &block
|
54
|
+
src_enum = @filter.nil? ? @org_enum : self
|
55
|
+
FilterWithInitializer.new src_enum, init_proc, pattern||block
|
56
|
+
end
|
57
|
+
|
58
|
+
#[override]
|
59
|
+
def with_index offset=0, &block
|
60
|
+
raise ArgumentError, "tried to call filter.with_index without a block" unless block_given?
|
61
|
+
i = offset - 1
|
62
|
+
with_initializer(Proc.new{i = offset - 1}) do |el|
|
63
|
+
block.call(el, i += 1)
|
36
64
|
end
|
37
65
|
end
|
38
|
-
self
|
39
|
-
end
|
40
66
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
67
|
+
private
|
68
|
+
def conv_proc pattern
|
69
|
+
case pattern
|
70
|
+
when nil
|
71
|
+
Proc.new{true}
|
72
|
+
when Proc
|
73
|
+
pattern
|
74
|
+
else
|
75
|
+
pattern.respond_to?(:to_proc) ? pattern.to_proc : Proc.new{|el|pattern===el}
|
76
|
+
end
|
47
77
|
end
|
48
|
-
self
|
49
78
|
end
|
50
79
|
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
80
|
+
# private
|
81
|
+
class FilterWithInitializer < Filter
|
82
|
+
def initialize obj, init_block, the_filter = nil
|
83
|
+
super obj, the_filter
|
84
|
+
@initializer = init_block
|
85
|
+
end
|
86
|
+
|
87
|
+
def each &block
|
88
|
+
return self unless block_given?
|
89
|
+
@initializer.call
|
90
|
+
super &block
|
60
91
|
end
|
61
|
-
Filter.new @org_enum, patterns
|
62
|
-
end
|
63
92
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
when nil
|
68
|
-
Proc.new{true}
|
69
|
-
when Proc
|
70
|
-
pattern
|
71
|
-
else
|
72
|
-
pattern.respond_to?(:to_proc) ? pattern.to_proc : Proc.new{|el|pattern===el}
|
93
|
+
#[override]
|
94
|
+
def filter pattern=nil, &block
|
95
|
+
Filter.new self, pattern||block
|
73
96
|
end
|
74
97
|
end
|
75
98
|
end
|
76
|
-
end
|
99
|
+
end
|
@@ -1,24 +1,15 @@
|
|
1
1
|
# for MacRuby
|
2
|
-
module Enumerable
|
3
|
-
def filter pattern = nil, &block
|
4
|
-
Filter.new self, pattern||block
|
5
|
-
end
|
6
|
-
|
7
|
-
def filter_with_initproc init_proc, pattern = nil, &block
|
8
|
-
Filter.new self, init_proc, pattern||block
|
9
|
-
end
|
10
2
|
|
3
|
+
class Enumerator
|
11
4
|
class Filter < Enumerator
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
TrueProc = Proc.new{true}
|
6
|
+
|
7
|
+
def initialize obj, the_filter = nil
|
15
8
|
@org_enum = obj
|
16
|
-
@init_block = init_block unless init_block.nil?
|
17
9
|
outer = self
|
18
10
|
super Class.new {
|
19
11
|
define_method :each do
|
20
12
|
return outer unless block_given?
|
21
|
-
init_block.call unless init_block.nil?
|
22
13
|
compiled_filter = outer.__send__(:compile_filter)
|
23
14
|
catch :do_break do
|
24
15
|
obj.each do |el|
|
@@ -50,10 +41,23 @@ module Enumerable
|
|
50
41
|
else
|
51
42
|
patterns<<(pattern || block)
|
52
43
|
end
|
53
|
-
return Filter.new @org_enum, @init_block, patterns unless @init_block.nil?
|
54
44
|
Filter.new @org_enum, patterns
|
55
45
|
end
|
56
46
|
|
47
|
+
def with_initializer init_proc, pattern = nil, &block
|
48
|
+
src_enum = @filter.nil? ? @org_enum : self
|
49
|
+
FilterWithInitializer.new src_enum, init_proc, pattern||block
|
50
|
+
end
|
51
|
+
|
52
|
+
#[override]
|
53
|
+
def with_index offset=0, &block
|
54
|
+
raise ArgumentError, "tried to call filter.with_index without a block" unless block_given?
|
55
|
+
i = offset - 1
|
56
|
+
patterns = @filter.nil? ? [] : @filter.clone
|
57
|
+
patterns << Proc.new{|el| block.call(el, i += 1)}
|
58
|
+
FilterWithInitializer.new @org_enum, Proc.new{i = offset - 1}, patterns
|
59
|
+
end
|
60
|
+
|
57
61
|
private
|
58
62
|
def conv_proc pattern
|
59
63
|
case pattern
|
@@ -74,4 +78,23 @@ module Enumerable
|
|
74
78
|
}.call(@filter)
|
75
79
|
end
|
76
80
|
end
|
81
|
+
|
82
|
+
# private
|
83
|
+
class FilterWithInitializer < Filter
|
84
|
+
def initialize obj, init_block, the_filter = nil
|
85
|
+
super obj, the_filter
|
86
|
+
@initializer = init_block
|
87
|
+
end
|
88
|
+
|
89
|
+
def each &block
|
90
|
+
return self unless block_given?
|
91
|
+
@initializer.call
|
92
|
+
super &block
|
93
|
+
end
|
94
|
+
|
95
|
+
#[override]
|
96
|
+
def filter pattern=nil, &block
|
97
|
+
Filter.new self, pattern||block
|
98
|
+
end
|
99
|
+
end
|
77
100
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
# for Ruby1.9.x except for MacRuby
|
2
|
-
module Enumerable
|
3
|
-
def transform &block
|
4
|
-
Transform.new self, &block
|
5
|
-
end
|
1
|
+
# -- for Ruby1.9.x except for MacRuby
|
6
2
|
|
3
|
+
# add [Filter] and [Transform] classes.
|
4
|
+
class Enumerator
|
5
|
+
# Lazy Transform Enumerator
|
7
6
|
class Transform < Enumerator
|
7
|
+
# @param [Enumerable] obj an Enumerable.
|
8
|
+
# @yield transform block.
|
8
9
|
def initialize obj, &transformer
|
9
10
|
@org_enum = obj
|
10
11
|
super() do |y|
|
@@ -16,13 +17,19 @@ module Enumerable
|
|
16
17
|
transform! &transformer if block_given?
|
17
18
|
end
|
18
19
|
|
20
|
+
# Apply another transformer block and return self. (bang method of transform)
|
21
|
+
# @yield [el] transform block.
|
22
|
+
# @return [Transform] self
|
19
23
|
def transform! &block
|
20
24
|
@transformer||=[]
|
21
25
|
@transformer << block if block_given?
|
22
26
|
self
|
23
27
|
end
|
24
28
|
|
25
|
-
#[override]
|
29
|
+
# [override] for performance
|
30
|
+
# @yield [el] transform block.
|
31
|
+
# @see Enumerable#transform Enumerable#transform
|
32
|
+
# @return [Transform]
|
26
33
|
def transform &block
|
27
34
|
# clone.transform! &block
|
28
35
|
cp = Transform.new @org_enum
|
@@ -32,6 +39,22 @@ module Enumerable
|
|
32
39
|
cp.transform! &block
|
33
40
|
end
|
34
41
|
|
42
|
+
# @yield [el, i]
|
43
|
+
# @overload with_index(offset=0, &block)
|
44
|
+
# @param [Numeric] offset offset.
|
45
|
+
# @yield [el, i]
|
46
|
+
# @return [Transform]
|
47
|
+
# @overload with_index(offset=0)
|
48
|
+
# @note same as with_index(offset) {|el, i| [el, i]}
|
49
|
+
# @param [Numeric] offset offset.
|
50
|
+
# @return [Transform]
|
51
|
+
# @return [Transform]
|
52
|
+
def with_index offset=0, &block
|
53
|
+
src_enum = @transformer.nil? || @transformer.size.zero? ? @org_enum : self
|
54
|
+
block ||= Proc.new{|el, i|[el, i]}
|
55
|
+
TransformWithIndex.new src_enum, offset, &block
|
56
|
+
end
|
57
|
+
|
35
58
|
private
|
36
59
|
def compile_transformer
|
37
60
|
return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
|
@@ -44,4 +67,30 @@ module Enumerable
|
|
44
67
|
}.call(@transformer)
|
45
68
|
end
|
46
69
|
end
|
70
|
+
|
71
|
+
# @api private
|
72
|
+
class TransformWithIndex < Transform
|
73
|
+
def initialize obj, offset = 0, &transformer
|
74
|
+
@org_enum = obj
|
75
|
+
@transformer = transformer.nil? ? nil : [transformer]
|
76
|
+
@offset = offset
|
77
|
+
end
|
78
|
+
|
79
|
+
def each
|
80
|
+
return self unless block_given?
|
81
|
+
the_transformer = @transformer[0] || Proc.new{|el,i|el}
|
82
|
+
i = @offset - 1
|
83
|
+
@org_enum.each do |el|
|
84
|
+
yield the_transformer.call(el, i+=1)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# @see Enumerable#filter Enumerable#filter
|
89
|
+
# @return [Transform]
|
90
|
+
def transform &block
|
91
|
+
Transform.new self, &block
|
92
|
+
end
|
93
|
+
alias :transform! :transform
|
94
|
+
end
|
95
|
+
private_constant :TransformWithIndex if self.respond_to? :private_constant
|
47
96
|
end
|
@@ -1,50 +1,79 @@
|
|
1
1
|
# for Ruby1.8.7
|
2
2
|
module Enumerable
|
3
|
-
|
4
|
-
Transform
|
5
|
-
|
3
|
+
class Enumerator
|
4
|
+
class Transform < Enumerator
|
5
|
+
def initialize obj, &transformer
|
6
|
+
@org_enum = obj
|
7
|
+
transform! &transformer if block_given?
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def each &block
|
11
|
+
return self unless block_given?
|
12
|
+
the_transformer = compile_transformer
|
13
|
+
@org_enum.each do |el|
|
14
|
+
block.call the_transformer[el]
|
15
|
+
end
|
16
|
+
self
|
17
|
+
end
|
12
18
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
block.call the_transformer[el]
|
19
|
+
def transform! &block
|
20
|
+
@transformer||=[]
|
21
|
+
@transformer << block if block_given?
|
22
|
+
self
|
18
23
|
end
|
19
|
-
self
|
20
|
-
end
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
#[override]
|
26
|
+
def transform &block
|
27
|
+
# clone.transform! &block
|
28
|
+
cp = Transform.new @org_enum
|
29
|
+
@transformer.each do |org_block|
|
30
|
+
cp.transform! &org_block
|
31
|
+
end unless @transformer.nil?
|
32
|
+
cp.transform! &block
|
33
|
+
end
|
27
34
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
#[override]
|
36
|
+
def with_index offset=0, &block
|
37
|
+
src_enum = @transformer.nil? || @transformer.size.zero? ? @org_enum : self
|
38
|
+
block ||= Proc.new{|el, i|[el, i]}
|
39
|
+
TransformWithIndex.new src_enum, offset, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def compile_transformer
|
44
|
+
return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
|
45
|
+
return @transformer[0] if @transformer.size==1
|
46
|
+
lambda{|t|
|
47
|
+
codes = t.size.times.inject "el" do |r,idx|
|
48
|
+
"t[#{idx}][#{r}]"
|
49
|
+
end
|
50
|
+
eval "Proc.new{|el|"+codes+"}"
|
51
|
+
}.call(@transformer)
|
52
|
+
end
|
36
53
|
end
|
37
54
|
|
38
|
-
private
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
55
|
+
# private
|
56
|
+
class TransformWithIndex < Transform
|
57
|
+
def initialize obj, offset = 0, &transformer
|
58
|
+
@org_enum = obj
|
59
|
+
@transformer = transformer.nil? ? nil : [transformer]
|
60
|
+
@offset = offset
|
61
|
+
end
|
62
|
+
|
63
|
+
def each
|
64
|
+
return self unless block_given?
|
65
|
+
the_transformer = @transformer[0] || Proc.new{|el,i|el}
|
66
|
+
i = @offset - 1
|
67
|
+
@org_enum.each do |el|
|
68
|
+
yield the_transformer.call(el, i+=1)
|
45
69
|
end
|
46
|
-
|
47
|
-
|
70
|
+
end
|
71
|
+
|
72
|
+
#[override]
|
73
|
+
def transform &block
|
74
|
+
Transform.new self, &block
|
75
|
+
end
|
76
|
+
alias :transform! :transform
|
48
77
|
end
|
49
78
|
end
|
50
79
|
end
|
@@ -1,9 +1,5 @@
|
|
1
1
|
# for MacRuby
|
2
|
-
|
3
|
-
def transform &block
|
4
|
-
Transform.new self, &block
|
5
|
-
end
|
6
|
-
|
2
|
+
class Enumerator
|
7
3
|
class Transform < Enumerator
|
8
4
|
def initialize obj, &transformer
|
9
5
|
@org_enum = obj
|
@@ -36,6 +32,13 @@ module Enumerable
|
|
36
32
|
cp.transform! &block
|
37
33
|
end
|
38
34
|
|
35
|
+
#[override]
|
36
|
+
def with_index offset=0, &block
|
37
|
+
src_enum = @transformer.nil? || @transformer.size.zero? ? @org_enum : self
|
38
|
+
block ||= Proc.new{|el, i|[el, i]}
|
39
|
+
TransformWithIndex.new src_enum, offset, &block
|
40
|
+
end
|
41
|
+
|
39
42
|
private
|
40
43
|
def compile_transformer
|
41
44
|
return Proc.new{|a|a} if @transformer.nil? || @transformer.size==0
|
@@ -52,4 +55,28 @@ module Enumerable
|
|
52
55
|
# }.call(@transformer)
|
53
56
|
end
|
54
57
|
end
|
58
|
+
|
59
|
+
# private
|
60
|
+
class TransformWithIndex < Transform
|
61
|
+
def initialize obj, offset = 0, &transformer
|
62
|
+
@org_enum = obj
|
63
|
+
@transformer = transformer.nil? ? nil : [transformer]
|
64
|
+
@offset = offset
|
65
|
+
end
|
66
|
+
|
67
|
+
def each
|
68
|
+
return self unless block_given?
|
69
|
+
the_transformer = @transformer[0] || Proc.new{|el,i|el}
|
70
|
+
i = @offset - 1
|
71
|
+
@org_enum.each do |el|
|
72
|
+
yield the_transformer.call(el, i+=1)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
#[override]
|
77
|
+
def transform &block
|
78
|
+
Transform.new self, &block
|
79
|
+
end
|
80
|
+
alias :transform! :transform
|
81
|
+
end
|
55
82
|
end
|
data/test/test_filter.rb
CHANGED
@@ -3,15 +3,17 @@ require 'enumerable_lz'
|
|
3
3
|
|
4
4
|
class FilterTest < Test::Unit::TestCase
|
5
5
|
def test_instance
|
6
|
-
|
6
|
+
filter_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Filter : Enumerator::Filter
|
7
|
+
enum = filter_class.new []
|
7
8
|
assert_not_nil(enum)
|
8
9
|
assert_kind_of(Enumerable, enum)
|
9
10
|
end
|
10
11
|
|
11
12
|
def test_filter_array
|
13
|
+
filter_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Filter : Enumerator::Filter
|
12
14
|
array = %w[Yes I have a number]
|
13
15
|
enum = array.filter{|letters|letters.size > 1}
|
14
|
-
assert_instance_of(
|
16
|
+
assert_instance_of(filter_class, enum)
|
15
17
|
assert_equal(%w[Yes have number], enum.to_a)
|
16
18
|
end
|
17
19
|
|
@@ -85,14 +87,15 @@ class FilterTest < Test::Unit::TestCase
|
|
85
87
|
assert_same(enum1, enum2)
|
86
88
|
end
|
87
89
|
|
88
|
-
def test_init_block
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
90
|
+
# def test_init_block
|
91
|
+
# range = -10..10
|
92
|
+
# cnt = 0
|
93
|
+
# init_pr = Proc.new{cnt = 0}
|
94
|
+
# filter_pr = Proc.new{(cnt+=1)<=10}
|
95
|
+
# # enum = Enumerator::FilterWithInitializer.new range, init_pr, filter_pr
|
96
|
+
# enum = Enumerator::FilterWithInitializer.new range, init_pr, filter_pr
|
97
|
+
# assert_equal([-10, -9, -8, -7, -6, -5, -4, -3, -2, -1], enum.to_a)
|
98
|
+
# end
|
96
99
|
|
97
100
|
def test_filter_with_initproc_1
|
98
101
|
range = -10..10
|
@@ -122,4 +125,22 @@ class FilterTest < Test::Unit::TestCase
|
|
122
125
|
enum = range.filter_with_initproc(init_pr) {|n|throw :do_break if (sum+=n)>100;true}
|
123
126
|
assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], enum.to_a)
|
124
127
|
end
|
128
|
+
|
129
|
+
def test_filetr_with_index
|
130
|
+
a = 0
|
131
|
+
b = (1..10).filter.with_index{|n,i|a=n;i.even?}.first
|
132
|
+
assert_equal([1, 1], [a, b])
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_filetr_with_index_2
|
136
|
+
a = 0
|
137
|
+
b = (1..10).filter.with_index(1){|n,i|a=n;i.even?}.first
|
138
|
+
assert_equal([2, 2], [a, b])
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_filetr_with_index_no_block
|
142
|
+
assert_raise(ArgumentError) do
|
143
|
+
(1..10).filter.with_index(2).take(2)
|
144
|
+
end
|
145
|
+
end
|
125
146
|
end
|
data/test/test_transform.rb
CHANGED
@@ -3,15 +3,17 @@ require 'enumerable_lz'
|
|
3
3
|
|
4
4
|
class TransformTest < Test::Unit::TestCase
|
5
5
|
def test_instance
|
6
|
-
|
6
|
+
transform_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Transform : Enumerator::Transform
|
7
|
+
enum = transform_class.new []
|
7
8
|
assert_not_nil(enum)
|
8
9
|
assert_kind_of(Enumerable, enum)
|
9
10
|
end
|
10
11
|
|
11
12
|
def test_transform_array
|
13
|
+
transform_class = RUBY_VERSION < "1.9.0" ? Enumerable::Enumerator::Transform : Enumerator::Transform
|
12
14
|
array = %w[Yes I have a number]
|
13
15
|
enum = array.transform{|letters|letters.swapcase}
|
14
|
-
assert_instance_of(
|
16
|
+
assert_instance_of(transform_class, enum)
|
15
17
|
assert_equal(%w[yES i HAVE A NUMBER], enum.to_a)
|
16
18
|
end
|
17
19
|
|
@@ -52,4 +54,24 @@ class TransformTest < Test::Unit::TestCase
|
|
52
54
|
enum2 = enum1.transform!
|
53
55
|
assert_same(enum1, enum2)
|
54
56
|
end
|
57
|
+
|
58
|
+
def test_transform_with_index
|
59
|
+
range = -10..10
|
60
|
+
a = 0
|
61
|
+
result = range.transform.with_index{|n,i|n+a=i}.take(10)
|
62
|
+
assert_equal(9, a)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_transform_with_index2
|
66
|
+
range = -10..10
|
67
|
+
a = 0
|
68
|
+
result = range.transform.with_index{|n,i|n+a=i}.take(10)
|
69
|
+
assert_equal([-10, -8, -6, -4, -2, 0, 2, 4, 6, 8], result)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_transform_with_index_no_block
|
73
|
+
range = -10..10
|
74
|
+
result = range.transform.with_index(2).filter{|n,i|n+i<10}.to_a
|
75
|
+
assert_equal([[-10, 2], [-9, 3], [-8, 4], [-7, 5], [-6, 6], [-5, 7], [-4, 8], [-3, 9], [-2, 10]], result)
|
76
|
+
end
|
55
77
|
end
|
metadata
CHANGED
@@ -1,28 +1,22 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumerable_lz
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
version: 0.1.4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.5
|
6
5
|
platform: ruby
|
7
|
-
authors:
|
6
|
+
authors:
|
8
7
|
- antimon2
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
|
13
|
-
date: 2011-05-07 00:00:00 +09:00
|
14
|
-
default_executable:
|
11
|
+
date: 2014-01-08 00:00:00.000000000 Z
|
15
12
|
dependencies: []
|
16
|
-
|
17
|
-
|
13
|
+
description: Add Enumerable#filter, Enumerable#transform and some equivalent methods
|
14
|
+
on Enumerable with suffix '_lz'.
|
18
15
|
email: antimon2.me@gmail.com
|
19
16
|
executables: []
|
20
|
-
|
21
17
|
extensions: []
|
22
|
-
|
23
18
|
extra_rdoc_files: []
|
24
|
-
|
25
|
-
files:
|
19
|
+
files:
|
26
20
|
- README.md
|
27
21
|
- LICENSE.txt
|
28
22
|
- ChangeLog
|
@@ -38,35 +32,35 @@ files:
|
|
38
32
|
- lib/enumerable_lz/transform_18.rb
|
39
33
|
- lib/enumerable_lz/transform_mrb.rb
|
40
34
|
- lib/enumerable_lz.rb
|
41
|
-
has_rdoc: true
|
42
35
|
homepage: https://github.com/antimon2/enumerable_lz
|
43
36
|
licenses: []
|
44
|
-
|
37
|
+
metadata: {}
|
45
38
|
post_install_message:
|
46
|
-
rdoc_options:
|
47
|
-
|
48
|
-
|
39
|
+
rdoc_options:
|
40
|
+
- --no-private
|
41
|
+
- --exclude
|
42
|
+
- (_mrb|_18)
|
43
|
+
require_paths:
|
49
44
|
- lib
|
50
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
- !ruby/object:Gem::Version
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - '>='
|
48
|
+
- !ruby/object:Gem::Version
|
55
49
|
version: 1.8.7
|
56
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
version: "0"
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
62
55
|
requirements: []
|
63
|
-
|
64
56
|
rubyforge_project: enumerable_lz
|
65
|
-
rubygems_version:
|
57
|
+
rubygems_version: 2.0.3
|
66
58
|
signing_key:
|
67
59
|
specification_version: 3
|
68
|
-
summary: Add Enumerable#filter, Enumerable#transform and some equivalent methods on
|
69
|
-
|
60
|
+
summary: Add Enumerable#filter, Enumerable#transform and some equivalent methods on
|
61
|
+
Enumerable with suffix '_lz'.
|
62
|
+
test_files:
|
70
63
|
- test/test_enumerable_ex.rb
|
71
64
|
- test/test_filter.rb
|
72
65
|
- test/test_transform.rb
|
66
|
+
has_rdoc: yard
|