enumerable_fu 0.1.0 → 0.1.1
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.
data/README.markdown
CHANGED
@@ -1,50 +1,84 @@
|
|
1
1
|
EnumerableFu
|
2
2
|
============
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
Lazy "filtering" and transforming
|
5
|
+
---------------------------------
|
6
6
|
|
7
|
-
|
7
|
+
EnumerableFu extends Enumerable with "lazy" versions of various common operations:
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
* `#selecting` selects elements that pass a test block (like `Enumerable#select`)
|
10
|
+
* `#rejecting` selects elements that fail a test block (like `Enumerable#reject`)
|
11
|
+
* `#collecting` applies a transforming block to each element (like `Enumerable#collect`)
|
12
|
+
* `#uniqing` discards duplicates (like `Enumerable#uniq`)
|
11
13
|
|
12
|
-
|
14
|
+
We say the "...ing" variants are "lazy", because they defer per-element processing until the result is used. They return Enumerable "result proxy" objects, rather than Arrays, and only perform the actual filtering (or transformation) as the result proxy is enumerated.
|
13
15
|
|
14
|
-
|
16
|
+
Perhaps an example would help. Consider the following snippet:
|
15
17
|
|
16
|
-
|
18
|
+
>> (1..10).collect { |x| puts "#{x}^2 = #{x*x}"; x*x }.take_while { |x| x < 20 }
|
19
|
+
1^2 = 1
|
20
|
+
2^2 = 4
|
21
|
+
3^2 = 9
|
22
|
+
4^2 = 16
|
23
|
+
5^2 = 25
|
24
|
+
6^2 = 36
|
25
|
+
7^2 = 49
|
26
|
+
8^2 = 64
|
27
|
+
9^2 = 81
|
28
|
+
10^2 = 100
|
29
|
+
=> [1, 4, 9, 16]
|
30
|
+
|
31
|
+
Here we use plain old `#collect` to square a bunch of numbers, and then grab the ones less than 20. We can do the same thing using `#collecting`, rather than `#collect`:
|
17
32
|
|
18
|
-
(1..
|
33
|
+
>> (1..10).collecting { |x| puts "#{x}^2 = #{x*x}"; x*x }.take_while { |x| x < 20 }
|
34
|
+
1^2 = 1
|
35
|
+
2^2 = 4
|
36
|
+
3^2 = 9
|
37
|
+
4^2 = 16
|
38
|
+
5^2 = 25
|
39
|
+
=> [1, 4, 9, 16]
|
19
40
|
|
20
|
-
|
41
|
+
Same result, but notice how only the first five inputs were ever squared; just enough to find the first result above 20.
|
21
42
|
|
22
|
-
|
43
|
+
Lazy pipelines
|
44
|
+
--------------
|
23
45
|
|
24
|
-
|
46
|
+
By combining two or more of the lazy operations provided by EnumerableFu, you can create an efficient "pipeline", e.g.
|
25
47
|
|
26
|
-
|
48
|
+
# enumerate all users
|
49
|
+
users = User.to_enum(:find_each)
|
27
50
|
|
28
|
-
|
51
|
+
# where first and last names start with the same letter
|
52
|
+
users = users.selecting { |u| u.first_name[0] == u.last_name[0] }
|
29
53
|
|
30
|
-
|
31
|
-
|
54
|
+
# grab their company (weeding out duplicates)
|
55
|
+
companies = users.collecting(&:company).uniqing
|
32
56
|
|
33
|
-
|
57
|
+
# resolve
|
58
|
+
companies.to_a #=> ["Disney"]
|
59
|
+
|
60
|
+
Because each processing step proceeds in parallel, without creation of intermediate collections (Arrays), you can efficiently operate on large (or even infinite) Enumerable collections.
|
61
|
+
|
62
|
+
Lazy combination of Enumerables
|
63
|
+
-------------------------------
|
64
|
+
|
65
|
+
EnumerableFu also provides some interesting ways to combine several Enumerable collections to create a new collection. Again, these operate "lazily".
|
66
|
+
|
67
|
+
`EnumerableFu.zipping` pulls elements from a number of collections in parallel, yielding each group.
|
34
68
|
|
35
69
|
array1 = [1,3,6]
|
36
70
|
array2 = [2,4,7]
|
37
|
-
|
71
|
+
EnumerableFu.zipping(array1, array2) # generates: [1,2], [3,4], [6,7]
|
38
72
|
|
39
|
-
`
|
73
|
+
`EnumerableFu.merging` merges multiple collections, preserving sort-order. The inputs are assumed to be sorted already.
|
40
74
|
|
41
75
|
array1 = [1,4,5]
|
42
76
|
array2 = [2,3,6]
|
43
|
-
|
77
|
+
EnumerableFu.merging(array1, array2) # generates: 1, 2, 3, 4, 5, 6
|
44
78
|
|
45
|
-
Variant `
|
79
|
+
Variant `EnumerableFu.merging_by` uses a block to determine sort-order.
|
46
80
|
|
47
81
|
array1 = %w(a dd cccc)
|
48
82
|
array2 = %w(eee bbbbb)
|
49
|
-
|
83
|
+
EnumerableFu.merging_by(array1, array2) { |x| x.length }
|
50
84
|
# generates: %w(a dd eee cccc bbbbb)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe EnumerableFu, :needs_enumerators => true do
|
4
4
|
|
5
5
|
describe ".merging" do
|
6
6
|
|
@@ -8,14 +8,14 @@ describe Enumerable, :needs_enumerators => true do
|
|
8
8
|
@array1 = [1,3,6]
|
9
9
|
@array2 = [2,4,7]
|
10
10
|
@array3 = [5,8]
|
11
|
-
@merge =
|
11
|
+
@merge = EnumerableFu.merging(@array1, @array2, @array3)
|
12
12
|
@merge.to_a.should == [1,2,3,4,5,6,7,8]
|
13
13
|
end
|
14
14
|
|
15
15
|
it "is lazy" do
|
16
16
|
@enum1 = [1,3]
|
17
17
|
@enum2 = [2,4].with_time_bomb
|
18
|
-
@merge =
|
18
|
+
@merge = EnumerableFu.merging(@enum1, @enum2)
|
19
19
|
@merge.take(4).should == [1,2,3,4]
|
20
20
|
end
|
21
21
|
|
@@ -26,7 +26,7 @@ describe Enumerable, :needs_enumerators => true do
|
|
26
26
|
it "uses the block to determine order" do
|
27
27
|
@array1 = %w(cccc dd a)
|
28
28
|
@array2 = %w(eeeee bbb)
|
29
|
-
@merge =
|
29
|
+
@merge = EnumerableFu.merging_by(@array1, @array2) { |s| -s.length }
|
30
30
|
@merge.to_a.should == %w(eeeee cccc bbb dd a)
|
31
31
|
end
|
32
32
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe EnumerableFu, :needs_enumerators => true do
|
4
4
|
|
5
5
|
describe "#zipping" do
|
6
6
|
|
@@ -8,12 +8,12 @@ describe Enumerable, :needs_enumerators => true do
|
|
8
8
|
@array1 = [1,3,6]
|
9
9
|
@array2 = [2,4,7]
|
10
10
|
@array3 = [5,8]
|
11
|
-
@zip =
|
11
|
+
@zip = EnumerableFu.zipping(@array1, @array2, @array3)
|
12
12
|
@zip.to_a.should == [[1,2,5], [3,4,8], [6,7,nil]]
|
13
13
|
end
|
14
14
|
|
15
15
|
it "is lazy" do
|
16
|
-
@zip =
|
16
|
+
@zip = EnumerableFu.zipping(%w(a b c), [1,2].with_time_bomb)
|
17
17
|
@zip.take(2).should == [["a", 1], ["b", 2]]
|
18
18
|
end
|
19
19
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: enumerable_fu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mike Williams
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-04-
|
13
|
+
date: 2011-04-24 00:00:00 +10:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|