facets 2.0.0 → 2.0.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.
@@ -5,5 +5,4 @@ require 'facets/enumerable/collate.rb'
5
5
  require 'facets/enumerable/collect.rb'
6
6
  require 'facets/enumerable/permutation.rb'
7
7
  require 'facets/enumerable/count.rb'
8
- require 'facets/enumerable/partition.rb'
9
8
  require 'facets/enumerable/probability.rb'
@@ -1,20 +1,43 @@
1
- # TITLE
1
+ # TITLE:
2
2
  #
3
3
  # Collect
4
4
  #
5
- # = DESCRIPTION
5
+ # DESCRIPTION:
6
6
  #
7
- # Enumerble collection extensions.
7
+ # Variations of Enumerable collection and partition methods.
8
8
  #
9
- # = AUTHORS
9
+ # AUTHORS:
10
10
  #
11
- # CREDIT Florian Gross
12
- # CREDIT Thomas Sawyer
13
- # CREDIT Gavin Sinclair
11
+ # - Florian Gross
12
+ # - Thomas Sawyer
13
+ # - Gavin Sinclair
14
+ # - Thibaut Barrère
15
+ # - WhyTheLuckyStiff
16
+ # - Daniel Sheppard
17
+ # - Paul Battley
18
+ #
19
+ # NOTES:
20
+ #
21
+ # - TODO Deprecate #group_by when released for Ruby 1.9.
22
+ # - TODO Suggest Enumerator's #each_slice use block arity if no parameter is given.
23
+
24
+ require 'enumerator' # for each_slice
14
25
 
15
26
  #
16
27
  module Enumerable
17
28
 
29
+ # Partition an array into parts of given length.
30
+ #
31
+ # CREDIT WhyTheLuckyStiff
32
+
33
+ # def / len
34
+ # inject([]) do |ary, x|
35
+ # ary << [] if [*ary.last].nitems % len == 0
36
+ # ary.last << x
37
+ # ary
38
+ # end
39
+ # end
40
+
18
41
  # Same as #collect but with an iteration counter.
19
42
  #
20
43
  # a = [1,2,3].collect_with_index { |e,i| e*i }
@@ -28,22 +51,7 @@ module Enumerable
28
51
  r
29
52
  end
30
53
 
31
- alias_method( :map_with_index, :collect_with_index )
32
-
33
- # DEPRECATE?
34
-
35
- # Why the term counter? There may be a change in Ruby 2.0
36
- # to use this word instead of index. Index will
37
- # still be used for Array, since that is the proper meaning
38
- # in that context. In the mean time, aliases are provided.
39
-
40
- alias_method( :collect_with_counter, :collect_with_index )
41
- alias_method( :map_with_counter, :collect_with_index )
42
-
43
- # More appropriate naming since an enumerable is not
44
- # neccesarily "indexed", as is an Array or Hash.
45
-
46
- alias_method :each_with_counter, :each_with_index
54
+ alias_method :map_with_index, :collect_with_index
47
55
 
48
56
  # Collects/Maps and filters items out in one single step.
49
57
  # You can use throw(:skip) in the supplied block to indicate that the
@@ -56,7 +64,7 @@ module Enumerable
56
64
  # end
57
65
  #
58
66
  # Also see Enumerable#collect, Enumerable#find_all.
59
- #
67
+
60
68
  def filter_collect #:yield:
61
69
  result = []
62
70
  self.each do |item|
@@ -78,7 +86,7 @@ module Enumerable
78
86
  # persons.compact_collect { |person| person.telephone_no }
79
87
  #
80
88
  # Also see Enumerable#collect, Enumerable#map, Array#compact.
81
- #
89
+
82
90
  def compact_collect #:yield:
83
91
  filter_collect do |item|
84
92
  new_item = yield(item)
@@ -91,65 +99,148 @@ module Enumerable
91
99
 
92
100
  # Say you want to count letters--
93
101
  #
94
- # some_text.injecting(Hash.new(0) {|h,l| h[l] += 1}
102
+ # some_text.injecting(Hash.new(0)) {|h,l| h[l] += 1}
95
103
  #
96
104
  # vs
97
105
  #
98
106
  # some_text.inject(Hash.new(0)) {|h,l| h[l] +=1; h}
99
107
  #
100
- #--
101
108
  # CREDIT Louis J Scoras
102
- #++
109
+
103
110
  def injecting(s)
104
111
  inject(s) do |k, i|
105
112
  yield(k, i); k
106
113
  end
107
114
  end
108
115
 
109
- end
110
-
116
+ # The #group_by method is best explained by example.
117
+ #
118
+ # (1..5).partition_by { |n| n % 3 }
119
+ # #=> { 0 => [3], 1 => [1, 4], 2 => [2,5] }
120
+ #
121
+ # ["I had", 1, "dollar and", 50, "cents"].partition_by { |e| e.class }
122
+ # #=> { String => ["I had","dollar and","cents"], Fixnum => [1,50] }
123
+ #
124
+ # #group_by is used to group items in a collection by something they
125
+ # have in common. The common factor is the key in the resulting hash, the
126
+ # array of like elements is the value.
127
+ #
128
+ # CREDIT Erik Veenstra
111
129
 
130
+ def group_by #:yield:
131
+ h = k = e = nil
132
+ r = Hash.new
133
+ each{ |e| (r[yield(e)] ||= []) << e }
134
+ r
135
+ end
112
136
 
113
- # _____ _
114
- # |_ _|__ ___| |_
115
- # | |/ _ \/ __| __|
116
- # | | __/\__ \ |_
117
- # |_|\___||___/\__|
118
- #
119
- =begin test
137
+ # This alias is the original Facets name for the method, but Ruby 1.9 has
138
+ # adopted #group_by as the name, so eventually #partition_by will be deprecated.
139
+ alias_method :partition_by, :group_by
120
140
 
121
- require 'test/unit'
141
+ # Similar to #group_by but returns an array of the groups.
142
+ # Returned elements are sorted by block.
143
+ #
144
+ # %w{this is a test}.cluster_by {|x| x[0]}
145
+ #
146
+ # _produces_
147
+ #
148
+ # [ ['a'], ['is'], ['this', 'test'] ]
149
+ #
150
+ # CREDIT Erik Veenstra
122
151
 
123
- class TestEnumerableCollect < Test::Unit::TestCase
152
+ def cluster_by(&b)
153
+ #group_by(&b).values
154
+ group_by(&b).sort.transpose.pop
155
+ end
124
156
 
125
- def test_filter_collect
126
- e = [3,4]
127
- a = [1,2,3,4].filter_collect { |n|
128
- throw(:skip) if n < 3
129
- n
130
- }
131
- assert_equal( e, a )
157
+ # Split on matching pattern.
158
+ #
159
+ # ['a1','b1','a2','b2'].divide(/^a/)
160
+ # => [['a1,'b1'],['a2','b2']]
161
+
162
+ def divide(pattern)
163
+ inject([]) do |memo,obj|
164
+ memo.push [] if pattern === obj
165
+ memo.last << obj
166
+ memo
132
167
  end
168
+ end
133
169
 
134
- def test_compact_collect
135
- a = [1,2,nil,4].compact_collect { |e| e }
136
- assert_equal( [1,2,4], a )
170
+ # Iterate through slices. If slicing +step+ is not
171
+ # given, the the arity if the block is used.
172
+ #
173
+ # x = []
174
+ # [1,2,3,4].each_by{ |a,b| x << [a,b] }
175
+ # x #=> [ [1,2], [3,4] ]
176
+ #
177
+ # x = []
178
+ # [1,2,3,4,5,6].each_by(3){ |a| x << a }
179
+ # x #=> [ [1,2,3], [4,5,6] ]
180
+
181
+ def each_by(step=nil, &yld)
182
+ if step
183
+ each_slice(step,&yld)
184
+ else
185
+ step = yld.arity.abs
186
+ each_slice(step,&yld)
137
187
  end
188
+ end
138
189
 
139
- def test_filter_collect
140
- e = [3,4]
141
- a = [1,2,3,4].filter_collect { |n|
142
- throw(:skip) if n < 3
143
- n
144
- }
145
- assert_equal( e, a )
190
+ # Iterators over each element pairing.
191
+ #
192
+ # [:a,:b,:c,:d].each_pair { |a,b| puts "#{a} -> #{b}" }
193
+ #
194
+ # _produces_
195
+ #
196
+ # a -> b
197
+ # c -> d
198
+
199
+ def each_pair #:yield:
200
+ e1 = nil
201
+ each_with_index do |e,i|
202
+ if i % 2 == 0
203
+ e1 = e
204
+ next
205
+ else
206
+ yield(e1,e)
207
+ end
146
208
  end
209
+ end
147
210
 
148
- def test_compact_collect
149
- a = [1,2,nil,4].compact_collect { |e| e }
150
- assert_equal( [1,2,4], a )
151
- end
211
+ # Collect each n items.
212
+ #
213
+ # CREDIT Martin DeMello
214
+
215
+ def eachn(&block)
216
+ n = block.arity.abs
217
+ each_slice(n) {|i| block.call(*i)}
218
+ end
219
+
220
+ # Conditional collect.
152
221
 
222
+ def collect_if(&b)
223
+ a = map(&b)
224
+ # to get the same semantics as select{|e| e}
225
+ a.delete(false)
226
+ a.compact!
227
+ a
153
228
  end
154
229
 
155
- =end
230
+ alias_method :map_if, :collect_if
231
+
232
+ # DEPRECATED
233
+ #
234
+ # # Why the term counter? There may be a change in Ruby 2.0
235
+ # # to use this word instead of index. Index will
236
+ # # still be used for Array, since that is the proper meaning
237
+ # # in that context. In the mean time, aliases are provided.
238
+ #
239
+ # alias_method( :collect_with_counter, :collect_with_index )
240
+ # alias_method( :map_with_counter, :collect_with_index )
241
+ #
242
+ # # More appropriate naming since an enumerable is not
243
+ # # neccesarily "indexed", as is an Array or Hash.
244
+ # alias_method :each_with_counter, :each_with_index
245
+
246
+ end
@@ -90,23 +90,21 @@ module Enumerable
90
90
  h2.keys
91
91
  end
92
92
 
93
- #
94
- def nonuniq!
95
- raise unless respond_to?(:replace)
96
- h1 = {}
97
- h2 = {}
98
- each {|i|
99
- h2[i] = true if h1[i]
100
- h1[i] = true
101
- }
102
- self.replace(h2.keys)
103
- end
93
+ # #
94
+ # def nonuniq!
95
+ # raise unless respond_to?(:replace)
96
+ # h1 = {}
97
+ # h2 = {}
98
+ # each {|i|
99
+ # h2[i] = true if h1[i]
100
+ # h1[i] = true
101
+ # }
102
+ # self.replace(h2.keys)
103
+ # end
104
104
 
105
105
  # Return list of dulicate elements.
106
106
 
107
- def duplicates
108
- inject(Hash.new(0)){|h,v| h[v]+=1; h}.reject{|k,v| v==1}.keys
109
- end
107
+ alias_method :duplicates, :nonuniq
110
108
 
111
109
  # Like #uniq, but determines uniqueness based on a given block.
112
110
  #
@@ -7,11 +7,16 @@ class Integer
7
7
  # a = 3.of { |i| "#{i+1}" }
8
8
  # a => [ "1", "2", "3" ]
9
9
  #
10
- def of(&yld)
11
- a = []; self.times{ |i| a << yld.call(i) }
12
- a
10
+ def of(&block)
11
+ Array.new(self, &block)
13
12
  end
14
13
 
14
+ #def of(&yld)
15
+ # a = []; self.times{ |i| a << yld.call(i) }
16
+ # a
17
+ #end
18
+
19
+ # Time warn aliases for #of.
15
20
  alias_method :times_collect, :of
16
21
  alias_method :times_map, :of
17
22
 
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -0,0 +1 @@
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -1 +1 @@
1
- require 'facets/enumerable/partition.rb'
1
+ require 'facets/enumerable/collect.rb'
@@ -4,7 +4,11 @@ LICENSE
4
4
  README
5
5
  demo
6
6
  demo/bench
7
- demo/bench/bench_factorial.rb
7
+ demo/bench/enumerable
8
+ demo/bench/enumerable/bench_collect.rb
9
+ demo/bench/enumerable/bench_count.rb
10
+ demo/bench/integer
11
+ demo/bench/integer/bench_factorial.rb
8
12
  demo/sample
9
13
  demo/sample/annotations
10
14
  demo/sample/annotations/annotations1.rb
@@ -56,7 +60,6 @@ lib/core/facets/enumerable/collect.rb
56
60
  lib/core/facets/enumerable/combination.rb
57
61
  lib/core/facets/enumerable/count.rb
58
62
  lib/core/facets/enumerable/instance_map.rb
59
- lib/core/facets/enumerable/partition.rb
60
63
  lib/core/facets/enumerable/permutation.rb
61
64
  lib/core/facets/enumerable/probability.rb
62
65
  lib/core/facets/enumerable.rb
@@ -287,6 +290,7 @@ lib/methods/facets/enumerable/filter_collect.rb
287
290
  lib/methods/facets/enumerable/filter_map.rb
288
291
  lib/methods/facets/enumerable/frequency.rb
289
292
  lib/methods/facets/enumerable/graph.rb
293
+ lib/methods/facets/enumerable/group_by.rb
290
294
  lib/methods/facets/enumerable/ideal_entropy.rb
291
295
  lib/methods/facets/enumerable/injecting.rb
292
296
  lib/methods/facets/enumerable/map_if.rb
@@ -815,7 +819,6 @@ test/unit/enumerable/test_collate.rb
815
819
  test/unit/enumerable/test_collect.rb
816
820
  test/unit/enumerable/test_combination.rb
817
821
  test/unit/enumerable/test_count.rb
818
- test/unit/enumerable/test_partition.rb
819
822
  test/unit/enumerable/test_permutation.rb
820
823
  test/unit/enumerable/test_probability.rb
821
824
  test/unit/file
@@ -1 +1 @@
1
- 2.0.0 stable (2007-10-03)
1
+ 2.0.1 stable (2007-10-03)
data/task/clean CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ratch
2
2
 
3
- CLOBBER = %w{ pkg doc/rdoc }
3
+ # Remove pkg/ and doc/rdoc products
4
4
 
5
- # Remove generated files
5
+ CLOBBER = %w{ pkg doc/rdoc }
6
6
 
7
7
  main :clean do
8
8
  CLOBBER.each do |f|
@@ -4,6 +4,7 @@
4
4
 
5
5
  main :groups do
6
6
  dir = 'lib/core/facets'
7
+
7
8
  Dir.chdir(dir) do
8
9
  dirs = Dir.glob('*').select{ |f| File.directory?(f) }
9
10
  dirs.each do |d|
@@ -5,8 +5,12 @@
5
5
  # This tool generates libraries files for each
6
6
  # method in the every facets library.
7
7
 
8
- require 'lib/core/facets/kernel/op_esc'
9
- require 'lib/core/facets/module/require'
8
+ $LOAD_PATH.unshift(File.expand_path('lib/methods'))
9
+ $LOAD_PATH.unshift(File.expand_path('lib/core'))
10
+ $LOAD_PATH.unshift(File.expand_path('lib/more'))
11
+
12
+ require 'facets/kernel/op_esc'
13
+ require 'facets/module/require'
10
14
 
11
15
  # Read configuration
12
16
 
@@ -56,7 +60,7 @@ task :generate_redirects => [ :neuter_module ] do
56
60
  redirect_libs.each do |file|
57
61
  next if dir?(file) #File.directory?(file)
58
62
 
59
- # puts "#{file}..."
63
+ puts "#{file}..."
60
64
 
61
65
  mod = Module.new
62
66
  mod.module_eval do