Enumerable

This is a simple reimplementation of the core Enumerable module to allow the methods to take and pass-on arbitrary arguments to the underlying # call. This library uses Enumerator and scans Enumerable so it can alwasy stay in sync.

NOTE Any Enumerable method with a negative arity cannot do pass arguments due to ambiguity in the argument count. So the methods # and # do NOT work this way, but simply work as they do in Enumerable. The method # (and #) though has been made to work by removing its rarely used optional parameter and providing instead an optional keyword parameter (:ifnone => …). Please keep these difference in mind.

  require 'enumargs'

  class T
    include Enumerable::Arguments
    def initialize(arr)
      @arr = arr
    end
    def each(n)
      arr.each{ |e| yield(e+n) }
    end
  end

  t = T.new([1,2,3])
  t.collect(4)
  #=> [5,6,7]

Constants

EWISE

Public Instance Methods

accumulate() click to toggle source

Accumulate a set of a set.

For example, in an ORM design if Group has_many User then

  groups.accumulate.users

will return a list of users from all groups.

CREDIT: George Moshchovitis

    # File lib/core/facets/enumerable/accumulate.rb, line 16
16:   def accumulate
17:     @_accumulate ||= Functor.new do |op, *args|
18:       inject([]) { |a, x| a << x.send(op, *args) }.flatten
19:     end
20:   end
cluster_by(&b) click to toggle source

Similar to # but returns an array of the groups. Returned elements are sorted by block.

   %w{this is a test}.cluster_by {|x| x[0]}

produces

   [ ['a'], ['is'], ['this', 'test'] ]

CREDIT: Erik Veenstra

    # File lib/core/facets/enumerable/cluster_by.rb, line 16
16:   def cluster_by(&b)
17:     group_by(&b).sort.transpose.pop || []   # group_by(&b).values ?
18:   end
collect_with_index() click to toggle source

Alias for map_with_index.

Alias for: map_with_index
collisions(&block) click to toggle source
Alias for: commonality
commonality(&block) click to toggle source

Returns all items that are equal in terms of the supplied block. If no block is given objects are considered to be equal if they return the same value for Object#hash and if obj1 == obj2.

  [1, 2, 2, 3, 4, 4].commonality # => { 2 => [2, 2], 4 => [4, 4] }

  ["foo", "bar", "a"].commonality { |str| str.length }
  # => { 3 => ["foo, "bar"] }

  # Returns all persons that share their last name with another person.
  persons.collisions { |person| person.last_name }

CREDIT: Florian Gross

    # File lib/core/facets/enumerable/commonality.rb, line 17
17:   def commonality(&block)
18:     had_no_block = !block
19:     block ||= lambda { |item| item }
20:     result = Hash.new { |hash, key| hash[key] = Array.new }
21:     self.each do |item|
22:       key = block.call(item)
23:       result[key] << item
24:     end
25:     result.reject! do |key, values|
26:       values.size <= 1
27:     end
28:     #return had_no_block ? result.values.flatten : result
29:     return result
30:   end
Also aliased as: collisions
compact_collect(&block) click to toggle source
Alias for: compact_map
compact_map(&block) click to toggle source

A more versitle # method. It can be used to collect and filter items out in one single step.

  [1,2,3].compact_map do |n|
    n < 1 ? nil : n
  end

produces

  [2,3]

CREDIT: Trans

DEPRECATE: This method should probably be removed b/c # does almost the same thing and enum.map{}.compact works too.

    # File lib/core/facets/enumerable/compact_map.rb, line 19
19:   def compact_map(&block)
20:     y = []
21:     if block_given?
22:       each do |*a|
23:         r = yield(*a)
24:         y << r unless r.nil?
25:       end
26:     else
27:       each do |r|
28:         y << r unless r.nil?
29:       end
30:     end
31:     y
32:   end
Also aliased as: compact_collect
count(*items, &block) click to toggle source

Count the number of items in an enumerable equal (==) to the given object(s).

  e = [ 'a', '1', 'a' ]
  e.count('1')     #=> 1
  e.count('a')     #=> 2
  e.count('a', 1)  #=> 3

Note that Hash#count only considers values.

  e = { 'a' => 2, 'x' => 2, 'b' => 1 }
  e.count(1) #=> 1
  e.count(2) #=> 2

CREDIT: Trans

    # File lib/core/facets/enumerable/count.rb, line 23
23:     def count(*items, &block)
24:       if block || !items.empty?
25:         r = self
26:         r = r.select(&block) if block
27:         r = r.select{ |x| items.any?{ |i| i == x } } if !items.empty?
28:         r.size
29:       else
30:         begin
31:           size
32:         rescue
33:           i=0; each{ |e| i+=1 }; i
34:         end
35:       end
36:     end
defer(&blk) click to toggle source

Without a block: wrap the Enumerable object in such a way that map, select and similar operations are performed “horizontally” across a series of blocks, instead of building an array of results at each step. This reduces memory usage, allows partial results to be provided early, and permits working with infinite series.

  a = (1..1_000_000_000).defer.select{ |i| i % 2 == 0 }.
                               map{ |i| i + 100 }.
                               take(10).to_a

With a block: the block acts as an arbitrary filter on the data. Unlike map, it can choose to drop elements from the result, and/or add additional ones. The first object passed to the block is the receiver of the output.

  (1..1_000_000_000).
    defer { |out,i| out << i if i % 2 == 0 }.  # like select
    defer { |out,i| out << i + 100 }.          # like map
    take(10).
    each { |i| puts i }

Use a method like to_a or to_h at the end of the chain when you want an Array or Hash built with the results, or each{…} if you just want to output each result and discard it.

    # File lib/core/facets/enumerable/defer.rb, line 30
30:   def defer(&blk)
31:     if block_given?
32:       Denumerator.new do |output|
33:         each do |*input|
34:           yield(output, *input)
35:         end
36:       end
37:     else
38:       Denumerator.new do |output|
39:         each do |*input|
40:           output.yield(*input)
41:         end
42:       end
43:     end
44:   end
divide(pattern) click to toggle source

Divide on matching pattern.

  ['a1','b1','a2','b2'].divide(/^a/)
  => [['a1,'b1'],['a2','b2']]

CREDIT: Trans

    # File lib/core/facets/enumerable/divide.rb, line 10
10:   def divide(pattern)
11:     memo = []
12:     each do |obj|
13:       memo.push [] if pattern === obj
14:       memo.last << obj
15:     end
16:     memo
17:   end
duplicates() click to toggle source

Return list of dulicate elements.

CREDIT: Thibaut Barrère

Alias for: nonuniq
each_by(steps=nil, &block) click to toggle source

Iterate through slices. If slice steps is not given, the arity of the block is used.

  x = []
  [1,2,3,4].each_by{ |a,b| x << [a,b] }
  x  #=> [ [1,2], [3,4] ]

  x = []
  [1,2,3,4,5,6].each_by(3){ |a| x << a }
  x  #=> [ [1,2,3], [4,5,6] ]

This is just like each_slice, except that it will check the arity of the block. If each_slice ever suppots this this method can be deprecated.

CREDIT: Trans

    # File lib/core/facets/enumerable/each_by.rb, line 22
22:   def each_by(steps=nil, &block)
23:     if steps
24:       each_slice(steps, &block)
25:     else
26:       steps = block.arity.abs
27:       each_slice(steps, &block)
28:       #each_slice(steps) {|i| block.call(*i)}
29:     end
30:   end
each_with_object(memo) click to toggle source

A variation of # that saves one from having to return the aggregate/memo argument.

Say we want to count characters in a string. Using the # method we have:

   string.each_with_object(Hash.new(0)) do |c, h|
     h[c] += 1
   end

versus using # which would be:

   string.inject(Hash.new(0)) do |h, c|
     h[c] +=1
     h
   end

Notice that the order of the block parameters is reversed.

This method used be called # and had the same parameter order as #, but Ruby 1.9 has adopted this method, so we support it instead.

    # File lib/core/facets/enumerable/each_with_object.rb, line 28
28:     def each_with_object(memo) #:yield:
29:       each do |element|
30:         yield(element, memo)
31:       end
32:       memo
33:     end
elementwise(count=1) click to toggle source

Long-term for #.

  a = [1,2]
  a.elementwise + 3          #=> [4,5]
  a.elementwise + [4,5]      #=> [5,7]
  a.elementwise + [[4,5],3]  #=> [[5,7],[4,5]
Alias for: ewise
entropy() click to toggle source

Shannon’s entropy for an array - returns the average bits per symbol required to encode the array. Lower values mean less “entropy” - i.e. less unique information in the array.

  %w{ a b c d e e e }.entropy  #=>

CREDIT: Derek

    # File lib/core/facets/enumerable/entropy.rb, line 14
14:   def entropy
15:     arr = to_a
16:     probHash = arr.probability
17:     # h is the Shannon entropy of the array
18:     h = 1.to_f * probHash.keys.inject(0.to_f) do |sum, i|
19:       sum + (probHash[i] * (Math.log(probHash[i])/Math.log(2.to_f)))
20:     end
21:     h
22:   end
every() click to toggle source

Returns an elemental object. This allows you to map a method on to every element.

  r = [1,2,3].every + 3  #=> [4,5,6]
    # File lib/core/facets/enumerable/every.rb, line 10
10:   def every
11:     per(:map)
12:   end
every!() click to toggle source

In place version of #.

    # File lib/core/facets/enumerable/every.rb, line 16
16:   def every!
17:     raise NoMethodError unless respond_to?(:map!)
18:     per(:map!)
19:   end
ewise(count=1) click to toggle source

Returns an elementwise Functor designed to make R-like elementwise operations possible. This is very much like the # method, but it treats array argument specially.

  [1,2].ewise + 3          #=> [4,5]
  [1,2].ewise + [4,5]      #=> [5,7]
  [1,2].ewise + [[4,5],3]  #=> [[5,7],[4,5]

Special thanks to Martin DeMello for helping to develop this.

    # File lib/core/facets/enumerable/ewise.rb, line 17
17:   def ewise(count=1)
18:     EWISE[[self,count]] ||= Functor.new do |op,*args|
19:       if args.empty?
20:         r = self
21:         count.times do
22:           r = r.collect{ |a| a.send(op) }
23:         end
24:         r
25:       else
26:         r = args.collect do |arg|
27:           if Array === arg #arg.kind_of?(Enumerable)
28:             x = self
29:             count.times do
30:               ln = (arg.length > length ? length : arg.length )
31:               x = x.slice(0...ln).zip(arg[0...ln]).collect{ |a,b| a.send(op,b) }
32:               #slice(0...ln).zip(arg[0...1n]).collect{ |a,b| b ? a.send(op,b) : nil }
33:             end
34:             x
35:           else
36:             x = self
37:             count.times do
38:               x = x.collect{ |a| a.send(op,arg) }
39:             end
40:             x
41:           end
42:         end
43:         r.flatten! if args.length == 1
44:         r
45:       end
46:     end
47:   end
Also aliased as: elementwise
exclude?(object) click to toggle source

The inverse of #.

   # File lib/core/facets/enumerable/exclude.rb, line 7
7:     def exclude?(object)
8:       !include?(object)
9:     end
filter(output=[]) click to toggle source

The block acts as an arbitrary filter on the data. Unlike map, it can choose to drop elements from the result and/or add additional elements. The first object passed to the block is the receiver of the output.

  (1..1_000_000_000).
    filter{ |out,i| out << i if i % 2 == 0 }.  # like select
    filter{ |out,i| out << i + 100 }.          # like map
    take(10).each{ |i| puts i }

This is very similar to #, but # handles argument better by reversing their order and using the splat operator.

    # File lib/core/facets/enumerable/filter.rb, line 17
17:   def filter(output=[]) #:yeild:
18:     if block_given?
19:       each do |*input|
20:         yield(output, *input)
21:       end
22:       output
23:     else
24:       to_enum(:filter)
25:     end
26:   end
find_yield(fallback=nil) click to toggle source

Yield each element to the block and return the result of the block when that result evaluates as true, terminating early like # and #.

  obj1.foo? #=> false
  obj2.foo? #=> true
  obj2.foo  #=> "value"

  [obj1, obj2].find_yield{ |obj| obj.foo if obj.foo? }     #=> "value"

Another example:

  [1,2,3,4,5].find_yield{ |i| j = i+1; j if j % 4 == 0 }   #=> "5"

If the block is never true, return the object given in the first parameter, or nil if none specified.

  [1,2,3].find_yield{ |_| false }    #=> nil
  [false].find_yield(1){ |_| false } #=> 1
    # File lib/core/facets/enumerable/find_yield.rb, line 23
23:   def find_yield(fallback=nil) #:yield:
24:     each do |member|
25:       result = yield(member)
26:       return result if result 
27:     end
28:     fallback
29:   end
frequency() click to toggle source

Generates a hash mapping each unique symbol in the array to the absolute frequency it appears.

CREDIT: Brian Schröder

    # File lib/core/facets/enumerable/frequency.rb, line 8
 8:   def frequency
 9:     #probs = Hash.new(0)
10:     #each do |e|
11:     #  probs[e] += 1
12:     #end
13:     #probs
14:     inject(Hash.new(0)){|h,v| h[v]+=1; h}
15:   end
graph(&yld) click to toggle source

Like #/#, but generates a Hash. The block is expected to return two values: the key and the value for the new hash.

  numbers  = (1..3)
  squares  = numbers.graph{ |n| [n, n*n] }   # { 1=>1, 2=>4, 3=>9 }
  sq_roots = numbers.graph{ |n| [n*n, n] }   # { 1=>1, 4=>2, 9=>3 }

CREDIT: Andrew Dudzik (adudzik), Trans

    # File lib/core/facets/enumerable/graph.rb, line 12
12:   def graph(&yld)
13:     if yld
14:       h = {}
15:       each do |*kv|
16:         r = yld[*kv]
17:         case r
18:         when Hash
19:           nk, nv = *r.to_a[0]
20:         when Range
21:           nk, nv = r.first, r.last
22:         else
23:           nk, nv = *r
24:         end
25:         h[nk] = nv
26:       end
27:       h
28:     else
29:       Enumerator.new(self,:graph)
30:     end
31:   end
Also aliased as: mash
group_by() click to toggle source

# is used to group items in a collection by something they have in common. The common factor is the key in the resulting hash, the array of like elements is the value.

  (1..5).group_by { |n| n % 3 }
       #=> { 0 => [3], 1 => [1, 4], 2 => [2,5] }

  ["I had", 1, "dollar and", 50, "cents"].group_by { |e| e.class }
       #=> { String => ["I had","dollar and","cents"], Fixnum => [1,50] }

CREDIT: Erik Veenstra

    # File lib/core/facets/enumerable/group_by.rb, line 17
17:     def group_by #:yield:
18:       #h = k = e = nil
19:       r = Hash.new
20:       each{ |e| (r[yield(e)] ||= []) << e }
21:       r
22:     end
ideal_entropy() click to toggle source

Returns the maximum possible Shannon entropy of the array with given size assuming that it is an “order-0” source (each element is selected independently of the next).

CREDIT: Derek

    # File lib/core/facets/enumerable/entropy.rb, line 30
30:   def ideal_entropy
31:     arr = to_a
32:     unitProb = 1.0.to_f / arr.size.to_f
33:     (1.to_f * arr.size.to_f * unitProb * Math.log(unitProb)/Math.log(2.to_f))
34:   end
map_detect(fallback=nil) click to toggle source

DEPRECATE: This has been renamed to #.

    # File lib/core/facets/enumerable/find_yield.rb, line 32
32:   def map_detect(fallback=nil)
33:     find_yield(fallback)
34:   end
map_send(meth, *args, &block) click to toggle source

Send a message to each element and collect the result.

CREDIT: Sean O’Halpin

   # File lib/core/facets/enumerable/map_send.rb, line 7
7:   def map_send(meth, *args, &block)
8:     map{|e| e.send(meth, *args, &block)}
9:   end
map_with_index() click to toggle source

Same as # but with an iteration counter.

  a = [1,2,3].collect_with_index { |e,i| e*i }
  a  #=> [0,2,6]

CREDIT: Gavin Sinclair

    # File lib/core/facets/enumerable/map_with_index.rb, line 10
10:   def map_with_index
11:     r = []
12:     each_with_index do |e, i|
13:       r << yield(e, i)
14:     end
15:     r
16:   end
Also aliased as: collect_with_index
mash(&yld) click to toggle source

Alias for #, which stands for “map hash”.

Alias for: graph
mode() click to toggle source

In Statistics mode is the value that occurs most frequently in a given set of data.

CREDIT: Robert Klemme

    # File lib/core/facets/enumerable/mode.rb, line 8
 8:   def mode
 9:     max = 0
10:     c = Hash.new 0
11:     each {|x| cc = c[x] += 1; max = cc if cc > max}
12:     c.select {|k,v| v == max}.map {|k,v| k}
13:   end
modulate(modulo) click to toggle source

Modulate. Divide an array into groups by modulo of the index.

2,4,6,8].modulate(2) #=> [[2,6],[4,8]

CREDIT: Trans

NOTE: Would the better name for this be ‘collate’?

    # File lib/core/facets/enumerable/modulate.rb, line 11
11:   def modulate(modulo)
12:     return to_a if modulo == 1
13:     raise ArgumentError, 'bad modulo' if size % modulo != 0
14:     r = Array.new(modulo, [])
15:     (0...size).each do |i|
16:       r[i % modulo] += [self[i]]
17:     end
18:     r
19:   end
none?() click to toggle source

Enumerable#none? is the logical opposite of the builtin method Enumerable#any?. It returns true if and only if none of the elements in the collection satisfy the predicate.

If no predicate is provided, Enumerable#none? returns true if and only if none of the elements have a true value (i.e. not nil or false).

  [].none?                      # true
  [nil].none?                   # true
  [5,8,9].none?                 # false
  (1...10).none? { |n| n < 0 }  # true
  (1...10).none? { |n| n > 0 }  # false

CREDIT: Gavin Sinclair

    # File lib/core/facets/enumerable/none.rb, line 21
21:     def none?  # :yield: e
22:       if block_given?
23:         not self.any? { |e| yield e }
24:       else
25:         not self.any?
26:       end
27:     end
nonuniq() click to toggle source

Returns a list on non-unique,

  [1,1,2,2,3,4,5].nonuniq  #=> [1,2]

CREDIT: Martin DeMello

    # File lib/core/facets/enumerable/duplicates.rb, line 9
 9:   def nonuniq
10:     h1 = {}
11:     h2 = {}
12:     each {|i|
13:       h2[i] = true if h1[i]
14:       h1[i] = true
15:     }
16:     h2.keys
17:   end
Also aliased as: duplicates
occur(n=nil) click to toggle source

Returns an array of elements for the elements that occur n times. Or according to the results of a given block.

  [1,1,2,3,3,4,5,5].occur(1)             #=> [2,4]
  [1,1,2,3,3,4,5,5].occur(2)             #=> [1,3,5]
  [1,1,2,3,3,4,5,5].occur(3)             #=> []

  [1,2,2,3,3,3].occur(1..1)              #=> [1]
  [1,2,2,3,3,3].occur(2..3)              #=> [2,3]

  [1,1,2,3,3,4,5,5].occur { |n| n == 1 } #=> [2,4]
  [1,1,2,3,3,4,5,5].occur { |n| n > 1 }  #=> [1,3,5]
    # File lib/core/facets/enumerable/occur.rb, line 16
16:   def occur(n=nil) #:yield:
17:     result = Hash.new { |hash, key| hash[key] = Array.new }
18:     self.each do |item|
19:       key = item
20:       result[key] << item
21:     end
22:     if block_given?
23:       result.reject! { |key, values| ! yield(values.size) }
24:     else
25:       raise ArgumentError unless n
26:       if Range === n
27:         result.reject! { |key, values| ! n.include?(values.size) }
28:       else
29:         result.reject! { |key, values| values.size != n }
30:       end
31:     end
32:     return result.values.flatten.uniq
33:   end
one?() click to toggle source

Enumerable#one? returns true if and only if exactly one element in the collection satisfies the given predicate.

If no predicate is provided, Enumerable#one? returns true if and only if exactly one element has a true value (i.e. not nil or false).

  [].one?                      # false
  [nil].one?                   # false
  [5].one?                     # true
  [5,8,9].one?                 # false
  (1...10).one? { |n| n == 5 } # true
  (1...10).one? { |n| n < 5 }  # false

CREDIT: Gavin Sinclair

    # File lib/core/facets/enumerable/one.rb, line 21
21:     def one?  # :yield: e
22:       matches = 0
23:       if block_given?
24:         self.each do |e|
25:           if yield(e)
26:             matches += 1
27:             return false if matches > 1
28:           end
29:         end
30:         return (matches == 1)
31:       else
32:         one? { |e| e }
33:       end
34:     end
per(enum_method=nil, *enum_args) click to toggle source

Per element meta-functor.

  [1,2,3].per + 3             #=> [4,5,6]
  [1,2,3].per(:map) + 3       #=> [4,5,6]
  [1,2,3].per(:select) > 1    #=> [2,3]

  [1,2,3].per.map + 3       #=> [4,5,6]
  [1,2,3].per.select > 1    #=> [2,3]
    # File lib/core/facets/enumerable/per.rb, line 18
18:   def per(enum_method=nil, *enum_args)
19:     if enum_method
20:       Permeator.new(self, enum_method, *enum_args)
21:       #Functor.new do |op, *args|
22:       #  __send__(enum_method, *enum_args){ |x| x.__send__(op, *args) } #, &blk) }
23:       #end
24:     else
25:       Functor.new do |enum_method, *enum_args|
26:         Permeator.new(self, enum_method, *enum_args)
27:         #Functor.new do |op, *args|
28:         #  __send__(enum_method, *enum_args){ |x| x.__send__(op, *args) } #, &blk) }
29:         #end
30:       end
31:     end
32:   end
probability() click to toggle source

Generates a hash mapping each unique element in the array to the relative frequency, i.e. the probablity, of it appearence.

CREDIT: Brian Schröder

    # File lib/core/facets/enumerable/probability.rb, line 9
 9:   def probability
10:     probs = Hash.new(0.0)
11:     size = 0.0
12:     each do | e |
13:       probs[e] += 1.0
14:       size += 1.0
15:     end
16:     probs.keys.each{ |e| probs[e] /= size }
17:     probs
18:   end
purge(*trash, &block) click to toggle source

A versitle compaction method. Like # but used to filter out multiple items in a single step.

Without trash arguments nil is assumed.

  [1, nil, 2].purge  #=> [1,2]

If trash arguments are given, each argument is compared for a match using #==.

  (1..6).purge(3,4)  #=> [1,2,5,6]

If a block is given, the yield is used in the matching condition instead of the element itsef.

  (1..6).purge(0){ |n| n % 2 }  #=> [1,3,5]

NOTE: This could just as well be an override of the core # method, but to avoid potential issues associated with overriding core methods we use the alternate name #.

CREDIT: Trans

    # File lib/core/facets/enumerable/purge.rb, line 27
27:   def purge(*trash, &block)
28:     trash = [nil] if trash.empty?
29:     r = []
30:     if block_given?
31:       each do |e|
32:         y = yield(e)
33:         r << e unless trash.any?{|t| t == y}
34:       end
35:     else
36:       each do |e|
37:         r << e unless trash.any?{|t| t == e}
38:       end
39:     end
40:     r
41:   end
recursive(opts={}) click to toggle source
   # File lib/core/facets/enumerable/recursive.rb, line 3
3:   def recursive(opts={})
4:     Recursor.new(self, opts)
5:   end
split(pattern) click to toggle source

Split on matching pattern. Unlike # this does not include matching elements.

  ['a1','a2','b1','a3','b2','a4'].split(/^b/)
  => [['a1','a2'],['a3'],['a4']]

CREDIT: Trans

    # File lib/core/facets/enumerable/split.rb, line 10
10:   def split(pattern)
11:     memo = []
12:     sect = []
13:     each do |obj|
14:       if pattern === obj
15:         memo << sect
16:         sect = []
17:       else
18:         sect << obj
19:       end
20:     end
21:     memo << sect
22:     memo.pop while memo.last == []
23:     memo
24:   end
sum(identity = 0, &block) click to toggle source

Uses #+ to sum the enumerated elements.

  [1,2,3].sum  #=> 6
  [3,3,3].sum  #=> 9
    # File lib/core/facets/enumerable/sum.rb, line 8
 8:   def sum(identity = 0, &block)
 9:     if block_given?
10:       map(&block).sum
11:     else
12:       inject{ |sum, element| sum + element } || identity
13:     end
14:   end
take(n) click to toggle source

Return the first n items from the collection

    # File lib/core/facets/enumerable/take.rb, line 7
 7:     def take(n)
 8:       res = []
 9:       count = 0
10:       each do |e|
11:         break if count >= n
12:         res << e
13:         count += 1
14:       end
15:       res
16:     end
threaded_map() click to toggle source

Like Enumerable#map but each iteration is processed via a separate thread.

CREDIT Sean O’Halpin

    # File lib/more/facets/thread.rb, line 37
37:   def threaded_map #:yield:
38:     map{ |e| Thread.new(e){ |t| yield(t) } }.map{ |t| t.value }
39:   end
threaded_map_send(meth, *args, &block) click to toggle source

Like Enumerable#map_send but each iteration is processed via a separate thread.

CREDIT Sean O’Halpin

    # File lib/more/facets/thread.rb, line 46
46:   def threaded_map_send(meth, *args, &block)
47:     map{ |e| Thread.new(e){ |t| t.send(meth, *args, &block) } }.map{ |t| t.value }
48:   end
to_h(mode=nil) click to toggle source

Convert an Enumerable object into a hash by first turning it into an array.

CREDIT: Trans

     # File lib/core/facets/to_hash.rb, line 225
225:   def to_h(mode=nil)
226:     to_a.to_h(mode)
227:   end
to_h_assoc() click to toggle source
     # File lib/core/facets/to_hash.rb, line 241
241:   def to_h_assoc
242:     to_a.to_h_assoc
243:   end
to_h_auto() click to toggle source
     # File lib/core/facets/to_hash.rb, line 229
229:   def to_h_auto
230:     to_a.to_h_auto
231:   end
to_h_flat() click to toggle source
     # File lib/core/facets/to_hash.rb, line 237
237:   def to_h_flat
238:     to_a.to_h_flat
239:   end
to_h_multi() click to toggle source
     # File lib/core/facets/to_hash.rb, line 245
245:   def to_h_multi
246:     to_a.to_h_multi
247:   end
to_h_splat() click to toggle source
     # File lib/core/facets/to_hash.rb, line 233
233:   def to_h_splat
234:     to_a.to_h_splat
235:   end
uniq_by() click to toggle source

Like #, but determines uniqueness based on a given block.

  (-5..5).to_a.uniq_by {|i| i*i }

produces

  [-5, -4, -3, -2, -1, 0]
    # File lib/core/facets/enumerable/uniq_by.rb, line 11
11:   def uniq_by #:yield:
12:     h = {}; inject([]) {|a,x| h[yield(x)] ||= a << x}
13:   end
visit(opts={}, &block) click to toggle source

Recursively iterate over all Enumerable elements, or subset given :type=>[type1, type2, ...].

  [1, 2, 8..9].visit{ |x| x.succ }
  # => [2, 3, [9, 10]]
    # File lib/core/facets/enumerable/visit.rb, line 9
 9:   def visit(opts={}, &block)
10:     type = opts[:type] ? [opts[:type]].flatten : [Enumerable]
11:     skip = opts[:skip]
12: 
13:     map do |v|
14:       case v
15:       when String # b/c of 1.8
16:         b.call(v)
17:       when *type
18:         v.recursive(opts).send(op,&b)
19:       else
20:         if skip && Enumerable === v
21:           v
22:         else
23:           b.call(v)
24:         end
25:       end
26:     end
27:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.