huge_enumerable 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -20
- data/Gemfile +3 -3
- data/LICENSE.txt +22 -22
- data/README.md +29 -29
- data/Rakefile +17 -17
- data/huge_enumerable.gemspec +28 -28
- data/lib/huge_enumerable.rb +362 -357
- data/lib/huge_enumerable/huge_collection.rb +83 -83
- data/lib/huge_enumerable/huge_combination.rb +112 -118
- data/lib/huge_enumerable/huge_permutation.rb +80 -67
- data/lib/huge_enumerable/huge_product.rb +77 -77
- data/lib/huge_enumerable/version.rb +4 -4
- data/spec/lib/huge_enumerable/huge_collection_spec.rb +32 -32
- data/spec/lib/huge_enumerable/huge_combination_spec.rb +38 -37
- data/spec/lib/huge_enumerable/huge_permutation_spec.rb +38 -37
- data/spec/lib/huge_enumerable/huge_product_spec.rb +34 -34
- data/spec/lib/huge_enumerable_spec.rb +641 -641
- metadata +97 -118
@@ -1,77 +1,77 @@
|
|
1
|
-
require 'huge_enumerable'
|
2
|
-
# HugePermutation is a HugeEnumerable style product. Comparable to Array#product.
|
3
|
-
# This class can be used to generate products of large arrays or anything else that responds to [].
|
4
|
-
# It is not necessary for the enumerables to be completely mapped into memory.
|
5
|
-
# They only have to be able to return the element mapped to the index given to [].
|
6
|
-
# ==== Examples
|
7
|
-
#
|
8
|
-
# Using HugeProduct directly:
|
9
|
-
#
|
10
|
-
# product = HugeProduct.new(('a'..'z').to_a, ('A'..'Z').to_a)
|
11
|
-
# product[0..4] # => [["a", "A"], ["a", "B"], ["a", "C"], ["a", "D"], ["a", "E"]]
|
12
|
-
# product[23..27] # => [["a", "X"], ["a", "Y"], ["a", "Z"], ["b", "A"], ["b", "B"]]
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# Subclassing HugeProduct
|
16
|
-
#
|
17
|
-
# class BabyGirlNames < HugeProduct
|
18
|
-
#
|
19
|
-
# def initialize
|
20
|
-
# first_names = %w{Emma Olivia Sophia Isabella Ava Mia Emily Charlotte Ella Amelia Abigail Madison Lily Chloe}
|
21
|
-
# middle_names = %w{Zoe Sophie Evelyn Aubrey Elizabeth Layla Anna Natalie Brooklyn Aria Audrey Ellie Lucy}
|
22
|
-
# super(first_names, middle_names)
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
# private
|
26
|
-
#
|
27
|
-
# def fetch(index)
|
28
|
-
# super(index).join(' ')
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# end
|
32
|
-
#
|
33
|
-
# name = BabyGirlNames.new
|
34
|
-
# name[0] # => "Emma Zoe"
|
35
|
-
# name[-1] # => "Chloe Lucy"
|
36
|
-
# size = name.size # => 182
|
37
|
-
# name[size / 2] # => "Charlotte Zoe"
|
38
|
-
class HugeProduct < HugeEnumerable
|
39
|
-
|
40
|
-
# Create a new HugeProduct
|
41
|
-
#
|
42
|
-
# ==== Attributes
|
43
|
-
#
|
44
|
-
# * +enumerable_a+ - Any enumerable that responds to []
|
45
|
-
# * +enumerable_b+ - Any enumerable that responds to [] (This can be the same object as enumerable_a)
|
46
|
-
#
|
47
|
-
# ==== Options
|
48
|
-
#
|
49
|
-
# * +:max_array_size+ - The default size of arrays when #to_a is called.
|
50
|
-
# * +:rng+ - The random number generator to use.
|
51
|
-
def initialize(enumerable_a, enumerable_b, max_array_size = nil, rng = nil)
|
52
|
-
@enum_a = enumerable_a
|
53
|
-
@enum_b = enumerable_b
|
54
|
-
super(max_array_size, rng)
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
attr_accessor :enum_a, :enum_b
|
60
|
-
|
61
|
-
def collection_size
|
62
|
-
enum_a_size * enum_b_size
|
63
|
-
end
|
64
|
-
|
65
|
-
def fetch(x)
|
66
|
-
[enum_a[x / enum_b_size], enum_b[x % enum_b_size]]
|
67
|
-
end
|
68
|
-
|
69
|
-
def enum_a_size
|
70
|
-
@enum_a_size ||= enum_a.size
|
71
|
-
end
|
72
|
-
|
73
|
-
def enum_b_size
|
74
|
-
@enum_b_size ||= enum_b.size
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
1
|
+
require 'huge_enumerable'
|
2
|
+
# HugePermutation is a HugeEnumerable style product. Comparable to Array#product.
|
3
|
+
# This class can be used to generate products of large arrays or anything else that responds to [].
|
4
|
+
# It is not necessary for the enumerables to be completely mapped into memory.
|
5
|
+
# They only have to be able to return the element mapped to the index given to [].
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# Using HugeProduct directly:
|
9
|
+
#
|
10
|
+
# product = HugeProduct.new(('a'..'z').to_a, ('A'..'Z').to_a)
|
11
|
+
# product[0..4] # => [["a", "A"], ["a", "B"], ["a", "C"], ["a", "D"], ["a", "E"]]
|
12
|
+
# product[23..27] # => [["a", "X"], ["a", "Y"], ["a", "Z"], ["b", "A"], ["b", "B"]]
|
13
|
+
#
|
14
|
+
#
|
15
|
+
# Subclassing HugeProduct
|
16
|
+
#
|
17
|
+
# class BabyGirlNames < HugeProduct
|
18
|
+
#
|
19
|
+
# def initialize
|
20
|
+
# first_names = %w{Emma Olivia Sophia Isabella Ava Mia Emily Charlotte Ella Amelia Abigail Madison Lily Chloe}
|
21
|
+
# middle_names = %w{Zoe Sophie Evelyn Aubrey Elizabeth Layla Anna Natalie Brooklyn Aria Audrey Ellie Lucy}
|
22
|
+
# super(first_names, middle_names)
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# private
|
26
|
+
#
|
27
|
+
# def fetch(index)
|
28
|
+
# super(index).join(' ')
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# name = BabyGirlNames.new
|
34
|
+
# name[0] # => "Emma Zoe"
|
35
|
+
# name[-1] # => "Chloe Lucy"
|
36
|
+
# size = name.size # => 182
|
37
|
+
# name[size / 2] # => "Charlotte Zoe"
|
38
|
+
class HugeProduct < HugeEnumerable
|
39
|
+
|
40
|
+
# Create a new HugeProduct
|
41
|
+
#
|
42
|
+
# ==== Attributes
|
43
|
+
#
|
44
|
+
# * +enumerable_a+ - Any enumerable that responds to []
|
45
|
+
# * +enumerable_b+ - Any enumerable that responds to [] (This can be the same object as enumerable_a)
|
46
|
+
#
|
47
|
+
# ==== Options
|
48
|
+
#
|
49
|
+
# * +:max_array_size+ - The default size of arrays when #to_a is called.
|
50
|
+
# * +:rng+ - The random number generator to use.
|
51
|
+
def initialize(enumerable_a, enumerable_b, max_array_size = nil, rng = nil)
|
52
|
+
@enum_a = enumerable_a
|
53
|
+
@enum_b = enumerable_b
|
54
|
+
super(max_array_size, rng)
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
attr_accessor :enum_a, :enum_b
|
60
|
+
|
61
|
+
def collection_size
|
62
|
+
enum_a_size * enum_b_size
|
63
|
+
end
|
64
|
+
|
65
|
+
def fetch(x)
|
66
|
+
[enum_a[x / enum_b_size], enum_b[x % enum_b_size]]
|
67
|
+
end
|
68
|
+
|
69
|
+
def enum_a_size
|
70
|
+
@enum_a_size ||= enum_a.size
|
71
|
+
end
|
72
|
+
|
73
|
+
def enum_b_size
|
74
|
+
@enum_b_size ||= enum_b.size
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class HugeEnumerable
|
2
|
-
# "0.0.1"
|
3
|
-
VERSION = "0.0.
|
4
|
-
end
|
1
|
+
class HugeEnumerable
|
2
|
+
# "0.0.1"
|
3
|
+
VERSION = "0.0.2"
|
4
|
+
end
|
@@ -1,33 +1,33 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeCollection do
|
4
|
-
|
5
|
-
let(:enumerable) { ('a'..'z').to_a }
|
6
|
-
|
7
|
-
subject(:collection) do
|
8
|
-
HugeCollection.send(:public, :collection_size)
|
9
|
-
HugeCollection.send(:public, :fetch)
|
10
|
-
HugeCollection.new(enumerable)
|
11
|
-
end
|
12
|
-
|
13
|
-
context "#collection_size" do
|
14
|
-
|
15
|
-
it "is equal to the original enumerable size" do
|
16
|
-
collection.collection_size.should eql(enumerable.size)
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
context "#fetch" do
|
22
|
-
|
23
|
-
it "returns values in the same order as enumerable[]" do
|
24
|
-
enumerable_fetches = []
|
25
|
-
collection_fetches = []
|
26
|
-
enumerable.size.times { |i| enumerable_fetches << enumerable[i] }
|
27
|
-
collection.collection_size.times { |i| collection_fetches << collection.fetch(i) }
|
28
|
-
collection_fetches.should eql(enumerable_fetches)
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HugeCollection do
|
4
|
+
|
5
|
+
let(:enumerable) { ('a'..'z').to_a }
|
6
|
+
|
7
|
+
subject(:collection) do
|
8
|
+
HugeCollection.send(:public, :collection_size)
|
9
|
+
HugeCollection.send(:public, :fetch)
|
10
|
+
HugeCollection.new(enumerable)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "#collection_size" do
|
14
|
+
|
15
|
+
it "is equal to the original enumerable size" do
|
16
|
+
collection.collection_size.should eql(enumerable.size)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
context "#fetch" do
|
22
|
+
|
23
|
+
it "returns values in the same order as enumerable[]" do
|
24
|
+
enumerable_fetches = []
|
25
|
+
collection_fetches = []
|
26
|
+
enumerable.size.times { |i| enumerable_fetches << enumerable[i] }
|
27
|
+
collection.collection_size.times { |i| collection_fetches << collection.fetch(i) }
|
28
|
+
collection_fetches.should eql(enumerable_fetches)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
33
|
end
|
@@ -1,38 +1,39 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeCombination do
|
4
|
-
|
5
|
-
let(:enumerable) { ('a'..'z').to_a }
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
HugeCombination.send(:public, :
|
10
|
-
HugeCombination.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@cache
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
combination_fetches.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HugeCombination do
|
4
|
+
|
5
|
+
let(:enumerable) { ('a'..'z').to_a }
|
6
|
+
let(:combination_size) { 3 }
|
7
|
+
|
8
|
+
subject(:combination) do
|
9
|
+
HugeCombination.send(:public, :collection_size)
|
10
|
+
HugeCombination.send(:public, :fetch)
|
11
|
+
HugeCombination.new(enumerable, combination_size)
|
12
|
+
end
|
13
|
+
|
14
|
+
def enum_combo(x)
|
15
|
+
@cache ||= {}
|
16
|
+
@cache[x.to_i] ||= enumerable.combination(x).to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#collection_size" do
|
20
|
+
|
21
|
+
it "is equal to array#combination.to_a.size" do
|
22
|
+
combination.collection_size.should eql(enum_combo(combination_size).size)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context "#fetch" do
|
28
|
+
|
29
|
+
it "returns values in the same order as array#combination.to_a[]" do
|
30
|
+
enum_combo_fetches = []
|
31
|
+
combination_fetches = []
|
32
|
+
enum_combo(combination_size).size.times { |i| enum_combo_fetches << enum_combo(combination_size)[i] }
|
33
|
+
combination.collection_size.times { |i| combination_fetches << combination.fetch(i) }
|
34
|
+
combination_fetches.should eql(enum_combo_fetches)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
38
39
|
end
|
@@ -1,38 +1,39 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugePermutation do
|
4
|
-
|
5
|
-
let(:enumerable) { ('a'..'z').to_a }
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
HugePermutation.send(:public, :
|
10
|
-
HugePermutation.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@cache
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
permutation_fetches.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HugePermutation do
|
4
|
+
|
5
|
+
let(:enumerable) { ('a'..'z').to_a }
|
6
|
+
let(:permutation_size) { 3 }
|
7
|
+
|
8
|
+
subject(:permutation) do
|
9
|
+
HugePermutation.send(:public, :collection_size)
|
10
|
+
HugePermutation.send(:public, :fetch)
|
11
|
+
HugePermutation.new(enumerable, permutation_size)
|
12
|
+
end
|
13
|
+
|
14
|
+
def enum_perm(x)
|
15
|
+
@cache ||= {}
|
16
|
+
@cache[x.to_i] ||= enumerable.permutation(x).to_a
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#collection_size" do
|
20
|
+
|
21
|
+
it "is equal to array#permutation.to_a.size" do
|
22
|
+
permutation.collection_size.should eql(enum_perm(permutation_size).size)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context "#fetch" do
|
28
|
+
|
29
|
+
it "returns values in the same order as array#permutation.to_a[]" do
|
30
|
+
enum_perm_fetches = []
|
31
|
+
permutation_fetches = []
|
32
|
+
enum_perm(permutation_size).size.times { |i| enum_perm_fetches << enum_perm(permutation_size)[i] }
|
33
|
+
permutation.collection_size.times { |i| permutation_fetches << permutation.fetch(i) }
|
34
|
+
permutation_fetches.should eql(enum_perm_fetches)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
38
39
|
end
|
@@ -1,35 +1,35 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe HugeProduct do
|
4
|
-
|
5
|
-
let(:enumerable_a) { ('a'..'z').to_a }
|
6
|
-
let(:enumerable_b) { ('A'..'Z').to_a }
|
7
|
-
let(:enum_prod) { enumerable_a.product(enumerable_b) }
|
8
|
-
|
9
|
-
subject(:product) do
|
10
|
-
HugeProduct.send(:public, :collection_size)
|
11
|
-
HugeProduct.send(:public, :fetch)
|
12
|
-
HugeProduct.new(enumerable_a, enumerable_b)
|
13
|
-
end
|
14
|
-
|
15
|
-
context "#collection_size" do
|
16
|
-
|
17
|
-
it "is equal to array#product(other_ary).size" do
|
18
|
-
product.collection_size.should eql(enum_prod.size)
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
context "#fetch" do
|
24
|
-
|
25
|
-
it "returns values in the same order as array#product(other_ary)[]" do
|
26
|
-
enum_prod_fetches = []
|
27
|
-
product_fetches = []
|
28
|
-
enum_prod.size.times { |i| enum_prod_fetches << enum_prod[i] }
|
29
|
-
product.collection_size.times { |i| product_fetches << product.fetch(i) }
|
30
|
-
product_fetches.should eql(enum_prod_fetches)
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HugeProduct do
|
4
|
+
|
5
|
+
let(:enumerable_a) { ('a'..'z').to_a }
|
6
|
+
let(:enumerable_b) { ('A'..'Z').to_a }
|
7
|
+
let(:enum_prod) { enumerable_a.product(enumerable_b) }
|
8
|
+
|
9
|
+
subject(:product) do
|
10
|
+
HugeProduct.send(:public, :collection_size)
|
11
|
+
HugeProduct.send(:public, :fetch)
|
12
|
+
HugeProduct.new(enumerable_a, enumerable_b)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "#collection_size" do
|
16
|
+
|
17
|
+
it "is equal to array#product(other_ary).size" do
|
18
|
+
product.collection_size.should eql(enum_prod.size)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#fetch" do
|
24
|
+
|
25
|
+
it "returns values in the same order as array#product(other_ary)[]" do
|
26
|
+
enum_prod_fetches = []
|
27
|
+
product_fetches = []
|
28
|
+
enum_prod.size.times { |i| enum_prod_fetches << enum_prod[i] }
|
29
|
+
product.collection_size.times { |i| product_fetches << product.fetch(i) }
|
30
|
+
product_fetches.should eql(enum_prod_fetches)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
35
|
end
|