source: EcnlProtoTool/trunk/mruby-2.1.1/mrblib/enum.rb@ 439

Last change on this file since 439 was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 7.3 KB
Line 
1##
2# Enumerable
3#
4# The <code>Enumerable</code> mixin provides collection classes with
5# several traversal and searching methods, and with the ability to
6# sort. The class must provide a method `each`, which
7# yields successive members of the collection. If
8# {Enumerable#max}, {#min}, or
9# {#sort} is used, the objects in the collection must also
10# implement a meaningful `<=>` operator, as these methods
11# rely on an ordering between members of the collection.
12#
13# @ISO 15.3.2
14module Enumerable
15
16 NONE = Object.new
17
18 ##
19 # Call the given block for each element
20 # which is yield by +each+. Return false
21 # if one block value is false. Otherwise
22 # return true. If no block is given and
23 # +self+ is false return false.
24 #
25 # ISO 15.3.2.2.1
26 def all?(&block)
27 if block
28 self.each{|*val| return false unless block.call(*val)}
29 else
30 self.each{|*val| return false unless val.__svalue}
31 end
32 true
33 end
34
35 ##
36 # Call the given block for each element
37 # which is yield by +each+. Return true
38 # if one block value is true. Otherwise
39 # return false. If no block is given and
40 # +self+ is true object return true.
41 #
42 # ISO 15.3.2.2.2
43 def any?(&block)
44 if block
45 self.each{|*val| return true if block.call(*val)}
46 else
47 self.each{|*val| return true if val.__svalue}
48 end
49 false
50 end
51
52 ##
53 # Call the given block for each element
54 # which is yield by +each+. Append all
55 # values of each block together and
56 # return this value.
57 #
58 # ISO 15.3.2.2.3
59 def collect(&block)
60 return to_enum :collect unless block
61
62 ary = []
63 self.each{|*val| ary.push(block.call(*val))}
64 ary
65 end
66
67 ##
68 # Return the first element for which
69 # value from the block is true. If no
70 # object matches, calls +ifnone+ and
71 # returns its result. Otherwise returns
72 # +nil+.
73 #
74 # ISO 15.3.2.2.4
75 def detect(ifnone=nil, &block)
76 return to_enum :detect, ifnone unless block
77
78 self.each{|*val|
79 if block.call(*val)
80 return val.__svalue
81 end
82 }
83 ifnone.call unless ifnone.nil?
84 end
85
86 ##
87 # Call the given block for each element
88 # which is yield by +each+. Pass an
89 # index to the block which starts at 0
90 # and increase by 1 for each element.
91 #
92 # ISO 15.3.2.2.5
93 def each_with_index(&block)
94 return to_enum :each_with_index unless block
95
96 i = 0
97 self.each{|*val|
98 block.call(val.__svalue, i)
99 i += 1
100 }
101 self
102 end
103
104 ##
105 # Return an array of all elements which
106 # are yield by +each+.
107 #
108 # ISO 15.3.2.2.6
109 def entries
110 ary = []
111 self.each{|*val|
112 # __svalue is an internal method
113 ary.push val.__svalue
114 }
115 ary
116 end
117
118 ##
119 # Alias for find
120 #
121 # ISO 15.3.2.2.7
122 alias find detect
123
124 ##
125 # Call the given block for each element
126 # which is yield by +each+. Return an array
127 # which contains all elements whose block
128 # value was true.
129 #
130 # ISO 15.3.2.2.8
131 def find_all(&block)
132 return to_enum :find_all unless block
133
134 ary = []
135 self.each{|*val|
136 ary.push(val.__svalue) if block.call(*val)
137 }
138 ary
139 end
140
141 ##
142 # Call the given block for each element
143 # which is yield by +each+ and which return
144 # value was true when invoking === with
145 # +pattern+. Return an array with all
146 # elements or the respective block values.
147 #
148 # ISO 15.3.2.2.9
149 def grep(pattern, &block)
150 ary = []
151 self.each{|*val|
152 sv = val.__svalue
153 if pattern === sv
154 ary.push((block)? block.call(*val): sv)
155 end
156 }
157 ary
158 end
159
160 ##
161 # Return true if at least one element which
162 # is yield by +each+ returns a true value
163 # by invoking == with +obj+. Otherwise return
164 # false.
165 #
166 # ISO 15.3.2.2.10
167 def include?(obj)
168 self.each{|*val|
169 return true if val.__svalue == obj
170 }
171 false
172 end
173
174 ##
175 # Call the given block for each element
176 # which is yield by +each+. Return value
177 # is the sum of all block values. Pass
178 # to each block the current sum and the
179 # current element.
180 #
181 # ISO 15.3.2.2.11
182 def inject(*args, &block)
183 raise ArgumentError, "too many arguments" if args.size > 2
184 if Symbol === args[-1]
185 sym = args[-1]
186 block = ->(x,y){x.__send__(sym,y)}
187 args.pop
188 end
189 if args.empty?
190 flag = true # no initial argument
191 result = nil
192 else
193 flag = false
194 result = args[0]
195 end
196 self.each{|*val|
197 val = val.__svalue
198 if flag
199 # push first element as initial
200 flag = false
201 result = val
202 else
203 result = block.call(result, val)
204 end
205 }
206 result
207 end
208 alias reduce inject
209
210 ##
211 # Alias for collect
212 #
213 # ISO 15.3.2.2.12
214 alias map collect
215
216 ##
217 # Return the maximum value of all elements
218 # yield by +each+. If no block is given <=>
219 # will be invoked to define this value. If
220 # a block is given it will be used instead.
221 #
222 # ISO 15.3.2.2.13
223 def max(&block)
224 flag = true # 1st element?
225 result = nil
226 self.each{|*val|
227 val = val.__svalue
228 if flag
229 # 1st element
230 result = val
231 flag = false
232 else
233 if block
234 result = val if block.call(val, result) > 0
235 else
236 result = val if (val <=> result) > 0
237 end
238 end
239 }
240 result
241 end
242
243 ##
244 # Return the minimum value of all elements
245 # yield by +each+. If no block is given <=>
246 # will be invoked to define this value. If
247 # a block is given it will be used instead.
248 #
249 # ISO 15.3.2.2.14
250 def min(&block)
251 flag = true # 1st element?
252 result = nil
253 self.each{|*val|
254 val = val.__svalue
255 if flag
256 # 1st element
257 result = val
258 flag = false
259 else
260 if block
261 result = val if block.call(val, result) < 0
262 else
263 result = val if (val <=> result) < 0
264 end
265 end
266 }
267 result
268 end
269
270 ##
271 # Alias for include?
272 #
273 # ISO 15.3.2.2.15
274 alias member? include?
275
276 ##
277 # Call the given block for each element
278 # which is yield by +each+. Return an
279 # array which contains two arrays. The
280 # first array contains all elements
281 # whose block value was true. The second
282 # array contains all elements whose
283 # block value was false.
284 #
285 # ISO 15.3.2.2.16
286 def partition(&block)
287 return to_enum :partition unless block
288
289 ary_T = []
290 ary_F = []
291 self.each{|*val|
292 if block.call(*val)
293 ary_T.push(val.__svalue)
294 else
295 ary_F.push(val.__svalue)
296 end
297 }
298 [ary_T, ary_F]
299 end
300
301 ##
302 # Call the given block for each element
303 # which is yield by +each+. Return an
304 # array which contains only the elements
305 # whose block value was false.
306 #
307 # ISO 15.3.2.2.17
308 def reject(&block)
309 return to_enum :reject unless block
310
311 ary = []
312 self.each{|*val|
313 ary.push(val.__svalue) unless block.call(*val)
314 }
315 ary
316 end
317
318 ##
319 # Alias for find_all.
320 #
321 # ISO 15.3.2.2.18
322 alias select find_all
323
324 ##
325 # Return a sorted array of all elements
326 # which are yield by +each+. If no block
327 # is given <=> will be invoked on each
328 # element to define the order. Otherwise
329 # the given block will be used for
330 # sorting.
331 #
332 # ISO 15.3.2.2.19
333 def sort(&block)
334 self.map{|*val| val.__svalue}.sort(&block)
335 end
336
337 ##
338 # Alias for entries.
339 #
340 # ISO 15.3.2.2.20
341 alias to_a entries
342
343 # redefine #hash 15.3.1.3.15
344 def hash
345 h = 12347
346 i = 0
347 self.each do |e|
348 h = __update_hash(h, i, e.hash)
349 i += 1
350 end
351 h
352 end
353end
Note: See TracBrowser for help on using the repository browser.