webget_ruby_ramp 1.7.2
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.tar.gz.sig +0 -0
- data/lib/webget_ruby_ramp.rb +250 -0
- data/lib/webget_ruby_ramp/active_record.rb +119 -0
- data/lib/webget_ruby_ramp/active_record/connection_adapters/abstract/schema_statements.rb +24 -0
- data/lib/webget_ruby_ramp/active_record/save_extensions.rb +35 -0
- data/lib/webget_ruby_ramp/array.rb +370 -0
- data/lib/webget_ruby_ramp/csv.rb +53 -0
- data/lib/webget_ruby_ramp/date.rb +90 -0
- data/lib/webget_ruby_ramp/enumerable.rb +385 -0
- data/lib/webget_ruby_ramp/file.rb +15 -0
- data/lib/webget_ruby_ramp/hash.rb +223 -0
- data/lib/webget_ruby_ramp/integer.rb +22 -0
- data/lib/webget_ruby_ramp/io.rb +65 -0
- data/lib/webget_ruby_ramp/kernel.rb +36 -0
- data/lib/webget_ruby_ramp/math.rb +20 -0
- data/lib/webget_ruby_ramp/nil.rb +17 -0
- data/lib/webget_ruby_ramp/numeric.rb +98 -0
- data/lib/webget_ruby_ramp/object.rb +20 -0
- data/lib/webget_ruby_ramp/process.rb +153 -0
- data/lib/webget_ruby_ramp/string.rb +221 -0
- data/lib/webget_ruby_ramp/symbol.rb +11 -0
- data/lib/webget_ruby_ramp/time.rb +11 -0
- data/lib/webget_ruby_ramp/xml.rb +193 -0
- data/lib/webget_ruby_ramp/yaml.rb +34 -0
- data/test/webget_ruby_ramp/active_record/connection_adapters/abstract/schema_statements_test.rb +9 -0
- data/test/webget_ruby_ramp/active_record/save_extensions_test.rb +7 -0
- data/test/webget_ruby_ramp/active_record_test.rb +64 -0
- data/test/webget_ruby_ramp/array_test.rb +171 -0
- data/test/webget_ruby_ramp/csv_test.rb +18 -0
- data/test/webget_ruby_ramp/date_test.rb +60 -0
- data/test/webget_ruby_ramp/enumerable_test.rb +275 -0
- data/test/webget_ruby_ramp/file_test.rb +15 -0
- data/test/webget_ruby_ramp/hash_test.rb +105 -0
- data/test/webget_ruby_ramp/integer_test.rb +19 -0
- data/test/webget_ruby_ramp/io_test.rb +31 -0
- data/test/webget_ruby_ramp/io_test.txt +1 -0
- data/test/webget_ruby_ramp/kernel_test.rb +15 -0
- data/test/webget_ruby_ramp/math_test.rb +17 -0
- data/test/webget_ruby_ramp/nil_test.rb +15 -0
- data/test/webget_ruby_ramp/numeric_test.rb +28 -0
- data/test/webget_ruby_ramp/object_test.rb +12 -0
- data/test/webget_ruby_ramp/process_test.rb +24 -0
- data/test/webget_ruby_ramp/string_test.rb +125 -0
- data/test/webget_ruby_ramp/symbol_test.rb +26 -0
- data/test/webget_ruby_ramp/time_test.rb +12 -0
- data/test/webget_ruby_ramp/xml_test.rb +93 -0
- data/test/webget_ruby_ramp/xml_test_1.xml +5 -0
- data/test/webget_ruby_ramp/xml_test_2.xml +5 -0
- data/test/webget_ruby_ramp/xml_test_msword_clean.html +1 -0
- data/test/webget_ruby_ramp/xml_test_msword_dirty.html +148 -0
- data/test/webget_ruby_ramp/yaml_test.rb +32 -0
- data/test/webget_ruby_ramp/yaml_test_1.yml +38 -0
- data/test/webget_ruby_ramp/yaml_test_2.yml +38 -0
- metadata +128 -0
- metadata.gz.sig +1 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# Comma Separated Values extensions
|
2
|
+
|
3
|
+
class CSV
|
4
|
+
|
5
|
+
# Return HTTP headers for a typical CSV file download without caching.
|
6
|
+
#
|
7
|
+
# ==Options
|
8
|
+
# - filename: defaults to "data.csv"
|
9
|
+
# - request: the incoming http request, which is used to return MSIE-specific headers
|
10
|
+
#
|
11
|
+
# ==Example
|
12
|
+
# headers = CSV.http_headers("myfile.csv")
|
13
|
+
#
|
14
|
+
# ==Example for Rails
|
15
|
+
# response.headers.merge CSV.http_headers("myfile.csv")
|
16
|
+
#
|
17
|
+
# Ideas from http://stackoverflow.com/questions/94502/in-rails-how-to-return-records-as-a-csv-file/94520
|
18
|
+
|
19
|
+
def self.http_headers(options={})
|
20
|
+
filename = options[:filename] || 'data.csv'
|
21
|
+
options=self.http_headers_adjust_for_broken_msie(options)
|
22
|
+
content_type = options[:content_type] || 'text/csv'
|
23
|
+
return options[:cache] \
|
24
|
+
? {
|
25
|
+
'Content-Type' => content_type,
|
26
|
+
'Content-Disposition' => "attachment; filename=\"#{filename}\"",
|
27
|
+
} \
|
28
|
+
: {
|
29
|
+
'Content-Type' => content_type,
|
30
|
+
'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
|
31
|
+
'Expires' => "0",
|
32
|
+
'Pragma' => 'no-cache',
|
33
|
+
'Content-Disposition' => "attachment; filename=\"#{filename}\"",
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
# Helper to try to "do the right thing" for the common case of Rails & MS IE.
|
38
|
+
#
|
39
|
+
# Rails automatically defines a _request_ object,
|
40
|
+
# that has an env HTTP_USER_AGENT.
|
41
|
+
|
42
|
+
def self.http_headers_adjust_for_broken_msie(options={})
|
43
|
+
request = options[:request] || request
|
44
|
+
msie = (request and request.env['HTTP_USER_AGENT'] =~ /msie/i)
|
45
|
+
if msie
|
46
|
+
options[:content_type]||='text/plain''})'
|
47
|
+
options[:cache]||=false
|
48
|
+
end
|
49
|
+
options
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
# Date extensions
|
4
|
+
|
5
|
+
class Date
|
6
|
+
|
7
|
+
|
8
|
+
# Return date in a sql format: YYYY-MM-DD
|
9
|
+
#
|
10
|
+
# ==Example
|
11
|
+
# d=Date.today
|
12
|
+
# d.to_sql => "2007-12-31"
|
13
|
+
|
14
|
+
def to_sql
|
15
|
+
return to_time.strftime("%Y-%m-%d")
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Return true if the date is a weekday: Mon, Tue, Wed, Thu, Fri
|
20
|
+
#
|
21
|
+
# ==Example
|
22
|
+
# d = Date.parse('2008-01-01')
|
23
|
+
# d.wday => 2
|
24
|
+
# d.weekday? => true
|
25
|
+
|
26
|
+
def weekday?
|
27
|
+
wday>0 and wday<6
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Return true if the date is a weekend: Sat, Sun
|
32
|
+
#
|
33
|
+
# ==Example
|
34
|
+
# d = Date.parse('2008-01-05')
|
35
|
+
# d.wday => 6
|
36
|
+
# d.weekend? => true
|
37
|
+
|
38
|
+
def weekend?
|
39
|
+
wday==0 or wday==6
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# Return a random date between min & max
|
44
|
+
#
|
45
|
+
# ==Example
|
46
|
+
# d1= Date.parse('2008-01-01')
|
47
|
+
# d2= Date.parse('2009-01-01')
|
48
|
+
# Date.between(d1,d3) => Date 2008-11-22
|
49
|
+
|
50
|
+
def self.between(min,max)
|
51
|
+
min+rand(max-min)
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
# Return the age in years for a given date.
|
56
|
+
#
|
57
|
+
# ==Example
|
58
|
+
#
|
59
|
+
# birthdate=Date.new(1980,10,31)
|
60
|
+
# birthdate.age_years => 28 (where 28 is the correct age for today)
|
61
|
+
#
|
62
|
+
# ==Example of custom dates
|
63
|
+
#
|
64
|
+
# birthdate=Date.new(1980,10,31)
|
65
|
+
#
|
66
|
+
# valentines = Date.new(2008,02,14)
|
67
|
+
# birthdate.age_years(valentines) => 27 # before the birthday
|
68
|
+
#
|
69
|
+
# halloween = Date.new(2008,10,31)
|
70
|
+
# birthdate.age_years(halloween) => 28 # on the birthday
|
71
|
+
#
|
72
|
+
# new_years_eve = Date.new(2008,12,31)
|
73
|
+
# birthdate.age_years(new_years_eve) => 28 # after the birthday
|
74
|
+
|
75
|
+
def age_years(compare_date=Date.today)
|
76
|
+
age=compare_date.year-year
|
77
|
+
compare_month = compare_date.month
|
78
|
+
age-=1 if compare_month < month or (compare_month==month and compare_date.day < day)
|
79
|
+
age
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Return the age in days for a given date.
|
84
|
+
|
85
|
+
def age_days(compare_to_date=Date.today)
|
86
|
+
(compare_to_date-self).to_i
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,385 @@
|
|
1
|
+
# Enumberable extensions
|
2
|
+
|
3
|
+
module Enumerable
|
4
|
+
|
5
|
+
|
6
|
+
########################################################################
|
7
|
+
#
|
8
|
+
# typecast
|
9
|
+
#
|
10
|
+
########################################################################
|
11
|
+
|
12
|
+
# Convert an enumerable to a hash.
|
13
|
+
#
|
14
|
+
# ==Example
|
15
|
+
# array=[[:a, :b],[:c, :d],[:e, :f]]
|
16
|
+
# array.to_h => {:a=>:b, :c=>:d, :e=>:f}
|
17
|
+
#
|
18
|
+
# If a key occurs more than once, then this will automatically
|
19
|
+
# convert the value to an array of the keys' values.
|
20
|
+
#
|
21
|
+
# ==Example
|
22
|
+
# array=[[:a,:b],[:a,:c],[:a,:d]]
|
23
|
+
# array.to_h => {:a=>[:b, :c, :d]}
|
24
|
+
|
25
|
+
def to_h
|
26
|
+
h={}
|
27
|
+
dupe={}
|
28
|
+
each{|k,v|
|
29
|
+
if h.key? k
|
30
|
+
if dupe.key? k
|
31
|
+
h[k] << v
|
32
|
+
else
|
33
|
+
h[k]=[h[k]]
|
34
|
+
h[k] << v
|
35
|
+
dupe[k]=true
|
36
|
+
end
|
37
|
+
else
|
38
|
+
h[k]=v
|
39
|
+
end
|
40
|
+
}
|
41
|
+
return h
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# Convert the enumerable to a hash by mapping each item to a key,item pair.
|
46
|
+
#
|
47
|
+
# ==Example
|
48
|
+
# strings = ["red","blue","green"]
|
49
|
+
# strings.index_by{|a| a.size]}
|
50
|
+
# => {3 => "red", 4 => "blue", 5 => "green"}
|
51
|
+
#
|
52
|
+
# Rails has this method.
|
53
|
+
#
|
54
|
+
# From http://stackoverflow.com/questions/412771/cleanest-way-to-create-a-hash-from-an-array
|
55
|
+
#
|
56
|
+
# Compare #hash_by
|
57
|
+
|
58
|
+
def index_by
|
59
|
+
inject({}) {|hash, elem| hash.merge!(yield(elem) => elem) }
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Convert the enumerable to a hash by mapping each item to a key,value pair.
|
64
|
+
#
|
65
|
+
# ==Example
|
66
|
+
# strings = ["red","blue","green"]
|
67
|
+
# strings.hash_by{|a| [a.size, a.titlecase]}
|
68
|
+
# => {3 => "red", 4 => "blue", 5 => "green"}
|
69
|
+
#
|
70
|
+
# Compare #index_by
|
71
|
+
|
72
|
+
def hash_by
|
73
|
+
map{|item| yield(item)}.to_h
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
########################################################################
|
79
|
+
#
|
80
|
+
# map_to_xxx
|
81
|
+
#
|
82
|
+
########################################################################
|
83
|
+
|
84
|
+
|
85
|
+
# Map each item => item.id
|
86
|
+
#
|
87
|
+
# ==Example
|
88
|
+
# users = User.find(:all)
|
89
|
+
# users.map_id => [1,2,3,4,...]
|
90
|
+
#
|
91
|
+
# A typical use is to convert a list of ActiveRecord items to a list of id items.
|
92
|
+
#
|
93
|
+
# This method is a fast way to get the same results as items.map(&:id)
|
94
|
+
|
95
|
+
def map_id
|
96
|
+
map{|item| item.id}
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Map each item => item.to_a
|
101
|
+
#
|
102
|
+
# ==Example
|
103
|
+
# set1 = Set.new([:a,:b,:c])
|
104
|
+
# set2 = Set.new([:d,:e,:f])
|
105
|
+
# set3 = Set.new([:g,:h,:i])
|
106
|
+
# sets = [set1, set2, set3]
|
107
|
+
# sets.map_to_a => [[:a, :b, :c], [:d, :e, :f], [:g, :h, :i]]
|
108
|
+
#
|
109
|
+
# A typical use is to convert a list with Set items to a list of Array items,
|
110
|
+
# so you can more easily iterate over the the Array items.
|
111
|
+
#
|
112
|
+
# See http://www.ruby-doc.org/core/classes/Enumerable.html#M003148
|
113
|
+
|
114
|
+
def map_to_a
|
115
|
+
map{|item| [item]}
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Map each item => item.to_f
|
120
|
+
#
|
121
|
+
# ==Example
|
122
|
+
# strings = ["1","2","3"]
|
123
|
+
# strings.map_to_f => [1.0, 2.0, 3.0]
|
124
|
+
#
|
125
|
+
# A typical use is to convert a list of String items to a list of float items.
|
126
|
+
#
|
127
|
+
# This method is a fast way to get the same results as items.map(&:to_f)
|
128
|
+
|
129
|
+
def map_to_f
|
130
|
+
map{|item| item.to_f}
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# Map each item => item.to_i
|
135
|
+
#
|
136
|
+
# ==Example
|
137
|
+
# strings = ["1","2","3"]
|
138
|
+
# strings.map_to_i => [1, 2, 3]
|
139
|
+
#
|
140
|
+
# A typical use is to convert a list of String items to a list of integer items.
|
141
|
+
#
|
142
|
+
# This method is a fast way to get the same results as items.map(&:to_i)
|
143
|
+
|
144
|
+
def map_to_i
|
145
|
+
map{|item| item.to_i}
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
# Map each item => item.to_s
|
150
|
+
#
|
151
|
+
# ==Example
|
152
|
+
# numbers = [1, 2, 3]
|
153
|
+
# numbers.map_to_s => ["1", "2", "3"]
|
154
|
+
#
|
155
|
+
# A typical use is to convert a list of Numeric items to a list of String items.
|
156
|
+
#
|
157
|
+
# This method is a fast way to get the same results as items.map(&:to_s)
|
158
|
+
|
159
|
+
def map_to_s
|
160
|
+
map{|item| item.to_s}
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# Map each item => item.to_sym
|
165
|
+
#
|
166
|
+
# ==Example
|
167
|
+
# strings = ["foo", "goo", "hoo"]
|
168
|
+
# strings.map_to_sym => [:foo, :goo, :hoo]
|
169
|
+
#
|
170
|
+
# A typical use is to convert a list of Object items to a list of Symbol items.
|
171
|
+
#
|
172
|
+
# This method is a fast way to get the same results as items.map(&:to_sym)
|
173
|
+
|
174
|
+
def map_to_sym
|
175
|
+
map{|item| item.to_sym}
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
# Map each item and its index => a new output
|
180
|
+
#
|
181
|
+
# cf. Enumerable#map, Enumerable#each_with_index
|
182
|
+
#
|
183
|
+
# ==Example
|
184
|
+
#
|
185
|
+
# strings = ["a", "b", "c"]
|
186
|
+
# strings.map_with_index{|string,index| "#{string}#{index}"}
|
187
|
+
# => ["a0, "b1", "c3"]
|
188
|
+
|
189
|
+
def map_with_index
|
190
|
+
index=-1
|
191
|
+
map{|item| index+=1; yield(item,index)}
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
########################################################################
|
196
|
+
#
|
197
|
+
# select
|
198
|
+
#
|
199
|
+
########################################################################
|
200
|
+
|
201
|
+
|
202
|
+
# enum.select_while {|obj| block } => array
|
203
|
+
# Returns an array containing the leading elements for which block is not false or nil.
|
204
|
+
|
205
|
+
def select_while
|
206
|
+
arr = []
|
207
|
+
each{|item| yield(item) ? (arr << item) : break}
|
208
|
+
return arr
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
# enum.select_until {|obj| block } => array
|
213
|
+
# Returns an array containing the leading elements for which block is false or nil.
|
214
|
+
|
215
|
+
def select_until
|
216
|
+
arr = []
|
217
|
+
each{|item| yield(item) ? break : (arr << item)}
|
218
|
+
return arr
|
219
|
+
end
|
220
|
+
|
221
|
+
|
222
|
+
# enum.select_with_index {|obj,i| block } => array
|
223
|
+
# Calls block with two arguments, the item and its index, for each item in enum.
|
224
|
+
# Returns an array containing the leading elements for which block is not false or nil.
|
225
|
+
|
226
|
+
def select_with_index
|
227
|
+
index = 0
|
228
|
+
arr = []
|
229
|
+
each{|item|
|
230
|
+
if yield(item,index)
|
231
|
+
arr << item
|
232
|
+
index+=1
|
233
|
+
else
|
234
|
+
break
|
235
|
+
end
|
236
|
+
}
|
237
|
+
return arr
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
########################################################################
|
242
|
+
#
|
243
|
+
# bisect
|
244
|
+
#
|
245
|
+
########################################################################
|
246
|
+
|
247
|
+
# enum.bisect {|obj| block} => array of positives, array of negatives
|
248
|
+
# Returns two arrays: the first contains the elements for which block is
|
249
|
+
# true, the second contains the elements for which block is false or nil.
|
250
|
+
|
251
|
+
def bisect
|
252
|
+
a=[]
|
253
|
+
b=[]
|
254
|
+
each{|x|
|
255
|
+
if yield(x)
|
256
|
+
a << x
|
257
|
+
else
|
258
|
+
b << x
|
259
|
+
end
|
260
|
+
}
|
261
|
+
return a,b
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
########################################################################
|
266
|
+
#
|
267
|
+
# nitems
|
268
|
+
#
|
269
|
+
########################################################################
|
270
|
+
|
271
|
+
|
272
|
+
# enum.nitems_while {| obj | block } => number of items
|
273
|
+
# Returns the number of leading elements for which block is not false or nil.
|
274
|
+
|
275
|
+
def nitems_while
|
276
|
+
num = 0
|
277
|
+
each{|item| yield(item) ? (num+=1) : break}
|
278
|
+
return num
|
279
|
+
end
|
280
|
+
|
281
|
+
|
282
|
+
# enum.nitems_until {| obj | block } => number of items
|
283
|
+
# Returns the number of leading elements for which block is false.
|
284
|
+
|
285
|
+
def nitems_until
|
286
|
+
num = 0
|
287
|
+
each{|item|
|
288
|
+
if yield(item)
|
289
|
+
break
|
290
|
+
else
|
291
|
+
num+=1
|
292
|
+
end
|
293
|
+
}
|
294
|
+
return num
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
# enum.nitems_with_index {|obj,i| block } => number of items
|
299
|
+
# Calls block with two arguments, the item and its index, for each item in enum.
|
300
|
+
# Returns the number of leading elements for which block is true.
|
301
|
+
|
302
|
+
def nitems_with_index
|
303
|
+
index = 0
|
304
|
+
each{|item| yield(item,index) ? (index+=1) : break}
|
305
|
+
return index
|
306
|
+
end
|
307
|
+
|
308
|
+
|
309
|
+
# Shortcut to Array#join to concatenate the items into a string
|
310
|
+
|
311
|
+
def join(prefix=nil,suffix=nil)
|
312
|
+
to_a.join(prefix,suffix)
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
########################################################################
|
317
|
+
#
|
318
|
+
# set math
|
319
|
+
#
|
320
|
+
########################################################################
|
321
|
+
|
322
|
+
|
323
|
+
# Returns true if this _enum_ intersects another _enum_.
|
324
|
+
#
|
325
|
+
# @nb This implementation uses #to_a and array intersection.
|
326
|
+
# A developer may want to optimize this implementation for
|
327
|
+
# other classes, such as detecting whether a range intersects
|
328
|
+
# another range simply by comparing the ranges' min/max values.
|
329
|
+
#
|
330
|
+
# ==Examples
|
331
|
+
# ['a','b','c'].intersect?(['c','d','e'] => true
|
332
|
+
# ['a','b','c'].intersect?(['d','e','f'] => false
|
333
|
+
|
334
|
+
def intersect?(enum)
|
335
|
+
return ((self===enum and self.to_a.size>0) or ((self.to_a & enum.to_a).size>0))
|
336
|
+
end
|
337
|
+
|
338
|
+
|
339
|
+
# Return the cartesian product of the enumerations.
|
340
|
+
# http://en.wikipedia.org/wiki/Cartesian_product
|
341
|
+
#
|
342
|
+
# This is the fastest implementation we have found.
|
343
|
+
# It returns results in typical order.
|
344
|
+
#
|
345
|
+
# By Thomas Hafner
|
346
|
+
# See http://www.ruby-forum.com/topic/95519
|
347
|
+
#
|
348
|
+
# For our benchmarks, we also compared thesk:
|
349
|
+
# - By William James, http://www.ruby-forum.com/topic/95519
|
350
|
+
# - By Brian Schröäer, http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/151857
|
351
|
+
|
352
|
+
def self.cartesian_product(*enums)
|
353
|
+
result = [[]]
|
354
|
+
while [] != enums
|
355
|
+
t, result = result, []
|
356
|
+
b, *enums = enums
|
357
|
+
t.each do |a|
|
358
|
+
b.each do |n|
|
359
|
+
result << a + [n]
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
result
|
364
|
+
end
|
365
|
+
|
366
|
+
def cartesian_product(*enums)
|
367
|
+
Enumerable.cartesian_product(self,*enums)
|
368
|
+
end
|
369
|
+
|
370
|
+
|
371
|
+
# Return the power set: an array with all subsets of the enum's elements.
|
372
|
+
# http://en.wikipedia.org/wiki/Power_set
|
373
|
+
#
|
374
|
+
# This implementation is from
|
375
|
+
# http://johncarrino.net/blog/2006/08/11/powerset-in-ruby/
|
376
|
+
#
|
377
|
+
# ==Example
|
378
|
+
# [1,2,3].power_set.sort
|
379
|
+
# => [[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]]
|
380
|
+
|
381
|
+
def power_set
|
382
|
+
inject([[]]){|c,y|r=[];c.each{|i|r<<i;r<<i+[y]};r}
|
383
|
+
end
|
384
|
+
|
385
|
+
end
|