source: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-enum-ext/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: 22.5 KB
Line 
1##
2# Enumerable
3#
4module Enumerable
5 ##
6 # call-seq:
7 # enum.drop(n) -> array
8 #
9 # Drops first n elements from <i>enum</i>, and returns rest elements
10 # in an array.
11 #
12 # a = [1, 2, 3, 4, 5, 0]
13 # a.drop(3) #=> [4, 5, 0]
14
15 def drop(n)
16 n = n.__to_int
17 raise ArgumentError, "attempt to drop negative size" if n < 0
18
19 ary = []
20 self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 }
21 ary
22 end
23
24 ##
25 # call-seq:
26 # enum.drop_while {|arr| block } -> array
27 # enum.drop_while -> an_enumerator
28 #
29 # Drops elements up to, but not including, the first element for
30 # which the block returns +nil+ or +false+ and returns an array
31 # containing the remaining elements.
32 #
33 # If no block is given, an enumerator is returned instead.
34 #
35 # a = [1, 2, 3, 4, 5, 0]
36 # a.drop_while {|i| i < 3 } #=> [3, 4, 5, 0]
37
38 def drop_while(&block)
39 return to_enum :drop_while unless block
40
41 ary, state = [], false
42 self.each do |*val|
43 state = true if !state and !block.call(*val)
44 ary << val.__svalue if state
45 end
46 ary
47 end
48
49 ##
50 # call-seq:
51 # enum.take(n) -> array
52 #
53 # Returns first n elements from <i>enum</i>.
54 #
55 # a = [1, 2, 3, 4, 5, 0]
56 # a.take(3) #=> [1, 2, 3]
57
58 def take(n)
59 n = n.__to_int
60 i = n.to_i
61 raise ArgumentError, "attempt to take negative size" if i < 0
62 ary = []
63 return ary if i == 0
64 self.each do |*val|
65 ary << val.__svalue
66 i -= 1
67 break if i == 0
68 end
69 ary
70 end
71
72 ##
73 # call-seq:
74 # enum.take_while {|arr| block } -> array
75 # enum.take_while -> an_enumerator
76 #
77 # Passes elements to the block until the block returns +nil+ or +false+,
78 # then stops iterating and returns an array of all prior elements.
79 #
80 # If no block is given, an enumerator is returned instead.
81 #
82 # a = [1, 2, 3, 4, 5, 0]
83 # a.take_while {|i| i < 3 } #=> [1, 2]
84 #
85 def take_while(&block)
86 return to_enum :take_while unless block
87
88 ary = []
89 self.each do |*val|
90 return ary unless block.call(*val)
91 ary << val.__svalue
92 end
93 ary
94 end
95
96 ##
97 # Iterates the given block for each array of consecutive <n>
98 # elements.
99 #
100 # @return [nil]
101 #
102 # @example
103 # (1..10).each_cons(3) {|a| p a}
104 # # outputs below
105 # [1, 2, 3]
106 # [2, 3, 4]
107 # [3, 4, 5]
108 # [4, 5, 6]
109 # [5, 6, 7]
110 # [6, 7, 8]
111 # [7, 8, 9]
112 # [8, 9, 10]
113
114 def each_cons(n, &block)
115 n = n.__to_int
116 raise ArgumentError, "invalid size" if n <= 0
117
118 return to_enum(:each_cons,n) unless block
119 ary = []
120 n = n.to_i
121 self.each do |*val|
122 ary.shift if ary.size == n
123 ary << val.__svalue
124 block.call(ary.dup) if ary.size == n
125 end
126 nil
127 end
128
129 ##
130 # Iterates the given block for each slice of <n> elements.
131 #
132 # @return [nil]
133 #
134 # @example
135 # (1..10).each_slice(3) {|a| p a}
136 # # outputs below
137 # [1, 2, 3]
138 # [4, 5, 6]
139 # [7, 8, 9]
140 # [10]
141
142 def each_slice(n, &block)
143 n = n.__to_int
144 raise ArgumentError, "invalid slice size" if n <= 0
145
146 return to_enum(:each_slice,n) unless block
147 ary = []
148 n = n.to_i
149 self.each do |*val|
150 ary << val.__svalue
151 if ary.size == n
152 block.call(ary)
153 ary = []
154 end
155 end
156 block.call(ary) unless ary.empty?
157 nil
158 end
159
160 ##
161 # call-seq:
162 # enum.group_by {| obj | block } -> a_hash
163 # enum.group_by -> an_enumerator
164 #
165 # Returns a hash, which keys are evaluated result from the
166 # block, and values are arrays of elements in <i>enum</i>
167 # corresponding to the key.
168 #
169 # (1..6).group_by {|i| i%3} #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
170 #
171 def group_by(&block)
172 return to_enum :group_by unless block
173
174 h = {}
175 self.each do |*val|
176 key = block.call(*val)
177 sv = val.__svalue
178 h.key?(key) ? (h[key] << sv) : (h[key] = [sv])
179 end
180 h
181 end
182
183 ##
184 # call-seq:
185 # enum.sort_by { |obj| block } -> array
186 # enum.sort_by -> an_enumerator
187 #
188 # Sorts <i>enum</i> using a set of keys generated by mapping the
189 # values in <i>enum</i> through the given block.
190 #
191 # If no block is given, an enumerator is returned instead.
192
193 def sort_by(&block)
194 return to_enum :sort_by unless block
195
196 ary = []
197 orig = []
198 self.each_with_index{|e, i|
199 orig.push(e)
200 ary.push([block.call(e), i])
201 }
202 if ary.size > 1
203 ary.sort!
204 end
205 ary.collect{|e,i| orig[i]}
206 end
207
208 ##
209 # call-seq:
210 # enum.first -> obj or nil
211 # enum.first(n) -> an_array
212 #
213 # Returns the first element, or the first +n+ elements, of the enumerable.
214 # If the enumerable is empty, the first form returns <code>nil</code>, and the
215 # second form returns an empty array.
216 def first(*args)
217 case args.length
218 when 0
219 self.each do |*val|
220 return val.__svalue
221 end
222 return nil
223 when 1
224 i = args[0].__to_int
225 raise ArgumentError, "attempt to take negative size" if i < 0
226 ary = []
227 return ary if i == 0
228 self.each do |*val|
229 ary << val.__svalue
230 i -= 1
231 break if i == 0
232 end
233 ary
234 else
235 raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1)"
236 end
237 end
238
239 ##
240 # call-seq:
241 # enum.count -> int
242 # enum.count(item) -> int
243 # enum.count { |obj| block } -> int
244 #
245 # Returns the number of items in +enum+ through enumeration.
246 # If an argument is given, the number of items in +enum+ that
247 # are equal to +item+ are counted. If a block is given, it
248 # counts the number of elements yielding a true value.
249 def count(v=NONE, &block)
250 count = 0
251 if block
252 self.each do |*val|
253 count += 1 if block.call(*val)
254 end
255 else
256 if v == NONE
257 self.each { count += 1 }
258 else
259 self.each do |*val|
260 count += 1 if val.__svalue == v
261 end
262 end
263 end
264 count
265 end
266
267 ##
268 # call-seq:
269 # enum.flat_map { |obj| block } -> array
270 # enum.collect_concat { |obj| block } -> array
271 # enum.flat_map -> an_enumerator
272 # enum.collect_concat -> an_enumerator
273 #
274 # Returns a new array with the concatenated results of running
275 # <em>block</em> once for every element in <i>enum</i>.
276 #
277 # If no block is given, an enumerator is returned instead.
278 #
279 # [1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4]
280 # [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
281 def flat_map(&block)
282 return to_enum :flat_map unless block
283
284 ary = []
285 self.each do |*e|
286 e2 = block.call(*e)
287 if e2.respond_to? :each
288 e2.each {|e3| ary.push(e3) }
289 else
290 ary.push(e2)
291 end
292 end
293 ary
294 end
295 alias collect_concat flat_map
296
297 ##
298 # call-seq:
299 # enum.max_by {|obj| block } -> obj
300 # enum.max_by -> an_enumerator
301 #
302 # Returns the object in <i>enum</i> that gives the maximum
303 # value from the given block.
304 #
305 # If no block is given, an enumerator is returned instead.
306 #
307 # %w[albatross dog horse].max_by {|x| x.length } #=> "albatross"
308
309 def max_by(&block)
310 return to_enum :max_by unless block
311
312 first = true
313 max = nil
314 max_cmp = nil
315
316 self.each do |*val|
317 if first
318 max = val.__svalue
319 max_cmp = block.call(*val)
320 first = false
321 else
322 if (cmp = block.call(*val)) > max_cmp
323 max = val.__svalue
324 max_cmp = cmp
325 end
326 end
327 end
328 max
329 end
330
331 ##
332 # call-seq:
333 # enum.min_by {|obj| block } -> obj
334 # enum.min_by -> an_enumerator
335 #
336 # Returns the object in <i>enum</i> that gives the minimum
337 # value from the given block.
338 #
339 # If no block is given, an enumerator is returned instead.
340 #
341 # %w[albatross dog horse].min_by {|x| x.length } #=> "dog"
342
343 def min_by(&block)
344 return to_enum :min_by unless block
345
346 first = true
347 min = nil
348 min_cmp = nil
349
350 self.each do |*val|
351 if first
352 min = val.__svalue
353 min_cmp = block.call(*val)
354 first = false
355 else
356 if (cmp = block.call(*val)) < min_cmp
357 min = val.__svalue
358 min_cmp = cmp
359 end
360 end
361 end
362 min
363 end
364
365 ##
366 # call-seq:
367 # enum.minmax -> [min, max]
368 # enum.minmax { |a, b| block } -> [min, max]
369 #
370 # Returns two elements array which contains the minimum and the
371 # maximum value in the enumerable. The first form assumes all
372 # objects implement <code>Comparable</code>; the second uses the
373 # block to return <em>a <=> b</em>.
374 #
375 # a = %w(albatross dog horse)
376 # a.minmax #=> ["albatross", "horse"]
377 # a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"]
378
379 def minmax(&block)
380 max = nil
381 min = nil
382 first = true
383
384 self.each do |*val|
385 if first
386 val = val.__svalue
387 max = val
388 min = val
389 first = false
390 else
391 val = val.__svalue
392 if block
393 max = val if block.call(val, max) > 0
394 min = val if block.call(val, min) < 0
395 else
396 max = val if (val <=> max) > 0
397 min = val if (val <=> min) < 0
398 end
399 end
400 end
401 [min, max]
402 end
403
404 ##
405 # call-seq:
406 # enum.minmax_by { |obj| block } -> [min, max]
407 # enum.minmax_by -> an_enumerator
408 #
409 # Returns a two element array containing the objects in
410 # <i>enum</i> that correspond to the minimum and maximum values respectively
411 # from the given block.
412 #
413 # If no block is given, an enumerator is returned instead.
414 #
415 # %w(albatross dog horse).minmax_by { |x| x.length } #=> ["dog", "albatross"]
416
417 def minmax_by(&block)
418 return to_enum :minmax_by unless block
419
420 max = nil
421 max_cmp = nil
422 min = nil
423 min_cmp = nil
424 first = true
425
426 self.each do |*val|
427 if first
428 max = min = val.__svalue
429 max_cmp = min_cmp = block.call(*val)
430 first = false
431 else
432 if (cmp = block.call(*val)) > max_cmp
433 max = val.__svalue
434 max_cmp = cmp
435 end
436 if (cmp = block.call(*val)) < min_cmp
437 min = val.__svalue
438 min_cmp = cmp
439 end
440 end
441 end
442 [min, max]
443 end
444
445 ##
446 # call-seq:
447 # enum.none? [{ |obj| block }] -> true or false
448 # enum.none?(pattern) -> true or false
449 #
450 # Passes each element of the collection to the given block. The method
451 # returns <code>true</code> if the block never returns <code>true</code>
452 # for all elements. If the block is not given, <code>none?</code> will return
453 # <code>true</code> only if none of the collection members is true.
454 #
455 # If a pattern is supplied instead, the method returns whether
456 # <code>pattern === element</code> for none of the collection members.
457 #
458 # %w(ant bear cat).none? { |word| word.length == 5 } #=> true
459 # %w(ant bear cat).none? { |word| word.length >= 4 } #=> false
460 # %w{ant bear cat}.none?(/d/) #=> true
461 # [1, 3.14, 42].none?(Float) #=> false
462 # [].none? #=> true
463 # [nil, false].none? #=> true
464 # [nil, true].none? #=> false
465
466 def none?(pat=NONE, &block)
467 if pat != NONE
468 self.each do |*val|
469 return false if pat === val.__svalue
470 end
471 elsif block
472 self.each do |*val|
473 return false if block.call(*val)
474 end
475 else
476 self.each do |*val|
477 return false if val.__svalue
478 end
479 end
480 true
481 end
482
483 ##
484 # call-seq:
485 # enum.one? [{ |obj| block }] -> true or false
486 # enum.one?(pattern) -> true or false
487 #
488 # Passes each element of the collection to the given block. The method
489 # returns <code>true</code> if the block returns <code>true</code>
490 # exactly once. If the block is not given, <code>one?</code> will return
491 # <code>true</code> only if exactly one of the collection members is
492 # true.
493 #
494 # If a pattern is supplied instead, the method returns whether
495 # <code>pattern === element</code> for exactly one collection member.
496 #
497 # %w(ant bear cat).one? { |word| word.length == 4 } #=> true
498 # %w(ant bear cat).one? { |word| word.length > 4 } #=> false
499 # %w(ant bear cat).one? { |word| word.length < 4 } #=> false
500 # %w{ant bear cat}.one?(/t/) #=> false
501 # [nil, true, 99].one? #=> false
502 # [nil, true, false].one? #=> true
503 # [ nil, true, 99 ].one?(Integer) #=> true
504 # [].one? #=> false
505
506 def one?(pat=NONE, &block)
507 count = 0
508 if pat!=NONE
509 self.each do |*val|
510 count += 1 if pat === val.__svalue
511 return false if count > 1
512 end
513 elsif block
514 self.each do |*val|
515 count += 1 if block.call(*val)
516 return false if count > 1
517 end
518 else
519 self.each do |*val|
520 count += 1 if val.__svalue
521 return false if count > 1
522 end
523 end
524
525 count == 1 ? true : false
526 end
527
528 # ISO 15.3.2.2.1
529 # call-seq:
530 # enum.all? [{ |obj| block } ] -> true or false
531 # enum.all?(pattern) -> true or false
532 #
533 # Passes each element of the collection to the given block. The method
534 # returns <code>true</code> if the block never returns
535 # <code>false</code> or <code>nil</code>. If the block is not given,
536 # Ruby adds an implicit block of <code>{ |obj| obj }</code> which will
537 # cause #all? to return +true+ when none of the collection members are
538 # +false+ or +nil+.
539 #
540 # If a pattern is supplied instead, the method returns whether
541 # <code>pattern === element</code> for every collection member.
542 #
543 # %w[ant bear cat].all? { |word| word.length >= 3 } #=> true
544 # %w[ant bear cat].all? { |word| word.length >= 4 } #=> false
545 # %w[ant bear cat].all?(/t/) #=> false
546 # [1, 2i, 3.14].all?(Numeric) #=> true
547 # [nil, true, 99].all? #=> false
548 #
549 def all?(pat=NONE, &block)
550 if pat != NONE
551 self.each{|*val| return false unless pat === val.__svalue}
552 elsif block
553 self.each{|*val| return false unless block.call(*val)}
554 else
555 self.each{|*val| return false unless val.__svalue}
556 end
557 true
558 end
559
560 # ISO 15.3.2.2.2
561 # call-seq:
562 # enum.any? [{ |obj| block }] -> true or false
563 # enum.any?(pattern) -> true or false
564 #
565 # Passes each element of the collection to the given block. The method
566 # returns <code>true</code> if the block ever returns a value other
567 # than <code>false</code> or <code>nil</code>. If the block is not
568 # given, Ruby adds an implicit block of <code>{ |obj| obj }</code> that
569 # will cause #any? to return +true+ if at least one of the collection
570 # members is not +false+ or +nil+.
571 #
572 # If a pattern is supplied instead, the method returns whether
573 # <code>pattern === element</code> for any collection member.
574 #
575 # %w[ant bear cat].any? { |word| word.length >= 3 } #=> true
576 # %w[ant bear cat].any? { |word| word.length >= 4 } #=> true
577 # %w[ant bear cat].any?(/d/) #=> false
578 # [nil, true, 99].any?(Integer) #=> true
579 # [nil, true, 99].any? #=> true
580 # [].any? #=> false
581 #
582 def any?(pat=NONE, &block)
583 if pat != NONE
584 self.each{|*val| return true if pat === val.__svalue}
585 elsif block
586 self.each{|*val| return true if block.call(*val)}
587 else
588 self.each{|*val| return true if val.__svalue}
589 end
590 false
591 end
592
593 ##
594 # call-seq:
595 # enum.each_with_object(obj) { |(*args), memo_obj| ... } -> obj
596 # enum.each_with_object(obj) -> an_enumerator
597 #
598 # Iterates the given block for each element with an arbitrary
599 # object given, and returns the initially given object.
600 #
601 # If no block is given, returns an enumerator.
602 #
603 # (1..10).each_with_object([]) { |i, a| a << i*2 }
604 # #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
605 #
606
607 def each_with_object(obj, &block)
608 return to_enum(:each_with_object, obj) unless block
609
610 self.each {|*val| block.call(val.__svalue, obj) }
611 obj
612 end
613
614 ##
615 # call-seq:
616 # enum.reverse_each { |item| block } -> enum
617 # enum.reverse_each -> an_enumerator
618 #
619 # Builds a temporary array and traverses that array in reverse order.
620 #
621 # If no block is given, an enumerator is returned instead.
622 #
623 # (1..3).reverse_each { |v| p v }
624 #
625 # produces:
626 #
627 # 3
628 # 2
629 # 1
630 #
631
632 def reverse_each(&block)
633 return to_enum :reverse_each unless block
634
635 ary = self.to_a
636 i = ary.size - 1
637 while i>=0
638 block.call(ary[i])
639 i -= 1
640 end
641 self
642 end
643
644 ##
645 # call-seq:
646 # enum.cycle(n=nil) { |obj| block } -> nil
647 # enum.cycle(n=nil) -> an_enumerator
648 #
649 # Calls <i>block</i> for each element of <i>enum</i> repeatedly _n_
650 # times or forever if none or +nil+ is given. If a non-positive
651 # number is given or the collection is empty, does nothing. Returns
652 # +nil+ if the loop has finished without getting interrupted.
653 #
654 # Enumerable#cycle saves elements in an internal array so changes
655 # to <i>enum</i> after the first pass have no effect.
656 #
657 # If no block is given, an enumerator is returned instead.
658 #
659 # a = ["a", "b", "c"]
660 # a.cycle { |x| puts x } # print, a, b, c, a, b, c,.. forever.
661 # a.cycle(2) { |x| puts x } # print, a, b, c, a, b, c.
662 #
663
664 def cycle(nv = nil, &block)
665 return to_enum(:cycle, nv) unless block
666
667 n = nil
668
669 if nv.nil?
670 n = -1
671 else
672 n = nv.__to_int
673 return nil if n <= 0
674 end
675
676 ary = []
677 each do |*i|
678 ary.push(i)
679 yield(*i)
680 end
681 return nil if ary.empty?
682
683 while n < 0 || 0 < (n -= 1)
684 ary.each do |i|
685 yield(*i)
686 end
687 end
688
689 nil
690 end
691
692 ##
693 # call-seq:
694 # enum.find_index(value) -> int or nil
695 # enum.find_index { |obj| block } -> int or nil
696 # enum.find_index -> an_enumerator
697 #
698 # Compares each entry in <i>enum</i> with <em>value</em> or passes
699 # to <em>block</em>. Returns the index for the first for which the
700 # evaluated value is non-false. If no object matches, returns
701 # <code>nil</code>
702 #
703 # If neither block nor argument is given, an enumerator is returned instead.
704 #
705 # (1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> nil
706 # (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 } #=> 34
707 # (1..100).find_index(50) #=> 49
708 #
709
710 def find_index(val=NONE, &block)
711 return to_enum(:find_index, val) if !block && val == NONE
712
713 idx = 0
714 if block
715 self.each do |*e|
716 return idx if block.call(*e)
717 idx += 1
718 end
719 else
720 self.each do |*e|
721 return idx if e.__svalue == val
722 idx += 1
723 end
724 end
725 nil
726 end
727
728 ##
729 # call-seq:
730 # enum.zip(arg, ...) -> an_array_of_array
731 # enum.zip(arg, ...) { |arr| block } -> nil
732 #
733 # Takes one element from <i>enum</i> and merges corresponding
734 # elements from each <i>args</i>. This generates a sequence of
735 # <em>n</em>-element arrays, where <em>n</em> is one more than the
736 # count of arguments. The length of the resulting sequence will be
737 # <code>enum#size</code>. If the size of any argument is less than
738 # <code>enum#size</code>, <code>nil</code> values are supplied. If
739 # a block is given, it is invoked for each output array, otherwise
740 # an array of arrays is returned.
741 #
742 # a = [ 4, 5, 6 ]
743 # b = [ 7, 8, 9 ]
744 #
745 # a.zip(b) #=> [[4, 7], [5, 8], [6, 9]]
746 # [1, 2, 3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
747 # [1, 2].zip(a, b) #=> [[1, 4, 7], [2, 5, 8]]
748 # a.zip([1, 2], [8]) #=> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
749 #
750 # c = []
751 # a.zip(b) { |x, y| c << x + y } #=> nil
752 # c #=> [11, 13, 15]
753 #
754
755 def zip(*arg, &block)
756 result = block ? nil : []
757 arg = arg.map do |a|
758 unless a.respond_to?(:to_a)
759 raise TypeError, "wrong argument type #{a.class} (must respond to :to_a)"
760 end
761 a.to_a
762 end
763
764 i = 0
765 self.each do |*val|
766 a = []
767 a.push(val.__svalue)
768 idx = 0
769 while idx < arg.size
770 a.push(arg[idx][i])
771 idx += 1
772 end
773 i += 1
774 if result.nil?
775 block.call(a)
776 else
777 result.push(a)
778 end
779 end
780 result
781 end
782
783 ##
784 # call-seq:
785 # enum.to_h -> hash
786 #
787 # Returns the result of interpreting <i>enum</i> as a list of
788 # <tt>[key, value]</tt> pairs.
789 #
790 # %i[hello world].each_with_index.to_h
791 # # => {:hello => 0, :world => 1}
792 #
793
794 def to_h(&blk)
795 h = {}
796 if blk
797 self.each do |v|
798 v = blk.call(v)
799 raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array
800 raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2
801 h[v[0]] = v[1]
802 end
803 else
804 self.each do |*v|
805 v = v.__svalue
806 raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array
807 raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2
808 h[v[0]] = v[1]
809 end
810 end
811 h
812 end
813
814 def uniq(&block)
815 hash = {}
816 if block
817 self.each do|*v|
818 v = v.__svalue
819 hash[block.call(v)] ||= v
820 end
821 else
822 self.each do|*v|
823 v = v.__svalue
824 hash[v] ||= v
825 end
826 end
827 hash.values
828 end
829
830 def filter_map(&blk)
831 return to_enum(:filter_map) unless blk
832
833 ary = []
834 self.each do |x|
835 x = blk.call(x)
836 ary.push x if x
837 end
838 ary
839 end
840
841 alias filter select
842
843 ##
844 # call-seq:
845 # enum.tally -> a_hash
846 #
847 # Tallys the collection. Returns a hash where the keys are the
848 # elements and the values are numbers of elements in the collection
849 # that correspond to the key.
850 #
851 # ["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
852 def tally
853 hash = {}
854 self.each do |x|
855 hash[x] = (hash[x]||0)+1
856 end
857 hash
858 end
859end
Note: See TracBrowser for help on using the repository browser.