Methods
Public Class methods
combinations(head, *rest)

Produces an array of arrays of all possible combinations of the given arrays in the position given. (Explain me better?)

  a = %w|a b|
  b = %w|a x|
  c = %w|x y|
  Array.combinations(a, b, c).each { |x| p x }

produces

  ["a", "a", "x"]
  ["a", "a", "y"]
  ["a", "x", "x"]
  ["a", "x", "y"]
  ["b", "a", "x"]
  ["b", "a", "y"]
  ["b", "x", "x"]
  ["b", "x", "y"]
# File lib/facets/core/enumerable/self/combinations.rb, line 23
  def self.combinations(head, *rest)
    crest = rest.empty? ? [[]] : combinations(*rest)
    head.inject([]) { |combs, item|
      combs + crest.map { |comb| [item] + comb }
    }
  end
cross(*enums, &block)

Provides the cross-product of two or more Enumerables. This is the class-level method. The instance method calls on this.

  Enumerable.cross([1,2], [4], ["apple", "banana"])
  #=> [[1, 4, "apple"], [1, 4, "banana"], [2, 4, "apple"], [2, 4, "banana"]]

  Enumerable.cross([1,2], [3,4])
  #=> [[1, 3], [1, 4], [2, 3], [2, 4]]
# File lib/facets/core/enumerable/self/cross.rb, line 21
  def self.cross(*enums, &block)

    raise if enums.empty?
    gens = enums.map{|e| Generator.new(e)}
    return [] if gens.any? {|g| g.end?}

    sz = gens.size
    res = []
    tuple = Array.new(sz)

    loop do
      # fill tuple
      (0 ... sz).each { |i|
        tuple[i] = gens[i].current
      }
      if block.nil?
        res << tuple.dup
      else
        block.call(tuple.dup)
      end

      # step forward
      gens[-1].next
      (sz-1).downto(0) do |i|
        if gens[i].end?
          if i > 0
            gens[i].rewind
            gens[i-1].next
          else
            return res
          end
        end
      end
    end #loop

  end
Public Instance methods
**(enum)

Operator alias for cross-product.

  a = [1,2] ** [4,5]
  a  #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
# File lib/facets/core/enumerable/op_pow.rb, line 11
  def **(enum)
    Enumerable.cross(self, enum)
  end
accumulate()

Project has_many Group Group has_many User projects.groups.accumulate.users

# File lib/facets/core/enumerable/accumulate.rb, line 16
  def accumulate
    Functor.new do |op, *args|
      self.inject([]) { |a, x| a << x.send(op, *args) }.flatten
    end  
  end
cascade(*methods)

Cascade actions on each enumerated element.

[9, 19, 29].cascade :succ, :to_s, :reverse

> ["01", "02", "03"]

# File lib/facets/core/enumerable/cascade.rb, line 12
  def cascade(*methods)
    methods.inject(self) { |ary, method| ary.map{ |x| x.send(method)}}
  end
collect_if(&b)
This method is also aliased as map_if
# File lib/facets/core/enumerable/collect_if.rb, line 4
  def collect_if(&b)
    a = map(&b)
    # to get the same semantics as select{|e| e}
    a.delete(false)
    a.compact!
    a
  end
collect_with_counter()

Alias for collect_with_index

collect_with_index() {|self[i], i| ...}

Same as collect but with an iteration counter.

  a = [1,2,3].collect_with_index { |e,i| e*i }
  a  #=> [0,2,6]
This method is also aliased as map_with_index collect_with_counter map_with_counter
# File lib/facets/core/enumerable/collect_with_index.rb, line 9
  def collect_with_index
    r = []
    each_index do |i|
      r << yield(self[i], i)
    end
    r
  end
commonality( &block )

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. No guarantee about the order of the elements in the resulting array is made.

Note: The result will be an array if you supply no block and a hash otherwise.

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

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

  # Returns all persons that share their last name with another person.
  persons.collisions { |person| person.last_name }
# File lib/facets/core/enumerable/commonality.rb, line 22
  def commonality( &block )
    had_no_block = !block
    block ||= lambda { |item| item }
    result = Hash.new { |hash, key| hash[key] = Array.new }
    self.each do |item|
      key = block.call(item)
      result[key] << item
    end
    result.reject! do |key, values|
      values.size <= 1
    end
    #return had_no_block ? result.values.flatten : result
    return result
  end
compact_collect( {|| ...}

Collects/Maps and compacts items in one single step. The items for which the supplied block returns nil will not end up in the resulting array.

  # Return telephone numbers of all persons that have a telephone number.
  persons.compact_collect { |person| person.telephone_no }

Also see Enumerable#collect, Enumerable#map, Array#compact.

This method is also aliased as compact_map
# File lib/facets/core/enumerable/compact_collect.rb, line 17
  def compact_collect #:yield:
    filter_collect do |item|
      new_item = yield(item)
      throw(:skip) if new_item.nil?
      new_item
    end
  end
compact_map(

Alias for compact_collect

count(*c)

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

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

Count can also handle multiple-valued blocks.

  e = { 'a' => 2, 'a' => 2, 'b' => 1 }
  e.count('a',2)  #=> 1
# File lib/facets/core/enumerable/count.rb, line 16
  def count(*c)
    self.select{ |*i| i == c }.length
  end
cross(*enums, &block)

The instance level cross-product method.

  a = []
  [1,2].cross([4,5]){|elem| a << elem }
  a  #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
# File lib/facets/core/enumerable/cross.rb, line 17
  def cross(*enums, &block)
    Enumerable.cross(self, *enums, &block)
  end
each_by(step=nil, &yld)

Alias for each_slice

each_pair( {|| ...}

Iterators ovr each element pairing.

  [:a,:b,:c,:d].each_pair { |a,b|  puts "#{a} -> #{b}" }

produces

  a -> b
  c -> d
# File lib/facets/core/enumerable/each_pair.rb, line 13
  def each_pair #:yield:
    e1 = nil
    each_with_index do |e,i|
      if i % 2 == 0
        e1 = e
        next
      else
        yield(e1,e)
      end
    end
  end
each_permutation() {|out| ...}

Applys a block to each possible permutation of an array/enumerable.

  %w[a b c].each_permutation { |x| puts(x.join('')) }

produces

  abc
  acb
  bac
  bca
  cab
  cba
# File lib/facets/core/enumerable/permute.rb, line 49
    def each_permutation()
        arr = to_a
        size = arr.size
        perm_count = (1...size).inject(0) { |s,x| s + x * x.factorial }
        weights = Array.new(size-1) {|i| (i+1).factorial }
        s = weights.size
        x,i,v,pos = nil
        0.upto(perm_count) do |v|
            out = arr[0..0]
            arr.each_with_index {|x,i|
                case i
                    when 0: next
                    when s: out.insert(v / weights[i-1], x)
                    else out.insert(v % weights[i] / weights[i-1], x)
                end
            }
            yield out
        end
    end
each_slice(step=nil, &yld)

Iterate through slices. If slicing step is not given, the the arity if the block is used.

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

  x = []
  [1,2,3,4,5,6].each_slice(3){ |a| x << a }
  x  #=> [ [1,2,3], [4,5,6] ]
This method is also aliased as each_by
# File lib/facets/core/enumerable/each_slice.rb, line 15
  def each_slice(step=nil, &yld)
    if step
      cnt = step
      n = length / cnt
      n += 1 if length % cnt > 0
      n.times { |i|
        yld.call(*self.slice(i*cnt,cnt))
      }
      return cnt
    else
      cnt = yld.arity.abs
      n = length / cnt
      n += 1 if length % cnt > 0
      n.times { |i|
        yld.call(*self.slice(i*cnt,cnt))
      }
      return cnt
    end
  end
elementwise()

Returns an elementwise Functor designed to make R-like elementwise operations possible.

  [1,2].ew + 3          #=> [4,5]
  [1,2].ew + [4,5]      #=> [5,7]
  [1,2].ew + [[4,5],3]  #=> [[5,7],[4,5]
This method is also aliased as ew
# File lib/facets/core/enumerable/ew.rb, line 16
  def elementwise
    Functor.new do |op,*args|
      a = args.collect do |arg|
        if arg.kind_of?(Enumerable)
          ln = ( arg.length > self.length ? self.length : arg.length )
          self[0...ln].zip(arg[0...ln]).collect{ |a,b| a.send(op,b) }
          #self[0...ln].zip(arg[0...1n]).collect{ |a,b| b ? a.send(op,b) : nil }
        else
          self.collect{ |a| a.send(op,arg) }
        end
      end
      a.flatten! if args.length == 1
      a
    end
  end
entropy()

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  #=>
# File lib/facets/core/enumerable/entropy.rb, line 15
  def entropy
    arr = self.to_a
    probHash = arr.probability
    # h is the Shannon entropy of the array
    h = -1.to_f * probHash.keys.inject(0.to_f) do |sum, i|
      sum + (probHash[i] * (Math.log(probHash[i])/Math.log(2.to_f)))
    end
    h
  end
every()

Returns an elementwise Functor. This allows you to map a method on to every element.

  [1,2,3].every + 3           #=> [4,5,6]

  ['a','b','c'].every.upcase  #=> ['A','B','C']
# File lib/facets/core/enumerable/every.rb, line 13
  def every
    Functor.new do |op,*args|
      self.collect{ |a| a.send(op,*args) }
    end
  end
ew()

Alias for elementwise

filter_collect( {|| ...}

Collects/Maps and filters items out in one single step. You can use throw(:skip) in the supplied block to indicate that the current item should not end up in the resulting array.

  # Return names of all person with an age of at least 18.
  persons.filter_collect do |person|
    throw(:skip) if person.age < 18
    person.name
  end

Also see Enumerable#collect, Enumerable#find_all.

This method is also aliased as filter_map
# File lib/facets/core/enumerable/filter_collect.rb, line 18
  def filter_collect #:yield:
    result = []
    self.each do |item|
      catch(:skip) do
        new_item = yield(item)
        result << new_item
      end
    end
    return result
  end
filter_map(

Alias for filter_collect

find_collisions( ) {|| ...}

Like commonality but returns an array if no block is given.

# File lib/facets/core/enumerable/find_collisions.rb, line 7
  def find_collisions( &blk ) #:yield:
    if block_given?
      commonality( &blk )
    else
      commonality.values.flatten.uniq
    end
  end
frequency()

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

# File lib/facets/core/enumerable/frequency.rb, line 8
  def frequency
    probs = Hash.new(0)
    each do | e |
      probs[e] += 1
    end
    probs
  end
graph(&yld)

Like map/collect, but it 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 }
# File lib/facets/core/enumerable/graph.rb, line 22
  def graph(&yld)
    if yld
      inject({}) do |h,kv|
        nk, nv = yld[*kv]
        h[nk] = nv
        h
      end
    else
      Hash[*self.to_a.flatten]
    end
  end
ideal_entropy()

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).

# File lib/facets/core/enumerable/ideal_entropy.rb, line 13
  def ideal_entropy
    arr = self.to_a
    unitProb = 1.0.to_f / arr.size.to_f
    (-1.to_f * arr.size.to_f * unitProb * Math.log(unitProb)/Math.log(2.to_f))
  end
map_if(&b)

Alias for collect_if

map_with_counter()

Alias for collect_with_index

map_with_index()

Alias for collect_with_index

mode()

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

# File lib/facets/core/enumerable/mode.rb, line 7
  def mode
    count = Hash.new(0)
    each {|x| count[x] += 1 }
    count.sort_by{|k,v|v}.last[0]
  end
none?( {|e| ...}

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
# File lib/facets/core/enumerable/none.rb, line 20
  def none?  # :yield: e
    if block_given?
      not self.any? { |e| yield e }
    else
      not self.any?
    end
  end
nonuniq()
# File lib/facets/core/enumerable/nonuniq.rb, line 7
  def nonuniq
    h1 = {}
    h2 = {}
    each {|i|
      h2[i] = true if h1[i]
      h1[i] = true
    }
    h2.keys 
  end
nonuniq!()
# File lib/facets/core/enumerable/nonuniq.rb, line 17
  def nonuniq!
    raise unless respond_to?(:replace)
    h1 = {}
    h2 = {}
    each {|i|
      h2[i] = true if h1[i]
      h1[i] = true
    }
    self.replace(h2.keys)
  end
occur(n=nil) {|| ...}

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/facets/core/enumerable/occur.rb, line 17
  def occur(n=nil) #:yield:
    result = Hash.new { |hash, key| hash[key] = Array.new }
    self.each do |item|
      key = item
      result[key] << item
    end
    if block_given?
      result.reject! { |key, values| ! yield(values.size) }
    else
      raise ArgumentError unless n
      if Range === n
        result.reject! { |key, values| ! n.include?(values.size) }
      else
        result.reject! { |key, values| values.size != n }
      end
    end
    return result.values.flatten.uniq
  end
one?( {|e| ...}

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
# File lib/facets/core/enumerable/one.rb, line 20
  def one?  # :yield: e
    matches = 0
    if block_given?
      self.each do |e|
        if yield(e)
          matches += 1
          return false if matches > 1
        end
      end
      return (matches == 1)
    else
      one? { |e| e }
    end
  end
partition_by( {|| ...}

See Enumerable#partition for the background. partition_by is best explained by example.

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

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

partition_by 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.

# File lib/facets/core/enumerable/partition_by.rb, line 19
  def partition_by #:yield:
    result = {}
    self.each do |e|
      value = yield e
      (result[value] ||= []) << e
    end
    result
  end
permutation_number(original_array=self.to_a.sort)
# File lib/facets/core/enumerable/permute.rb, line 22
    def permutation_number(original_array=self.to_a.sort)
        arr = to_a
        m = 1
        v = 0
        last_indicies = Hash.new(0)
        original_array.each_with_index {|x,i|
            next if i==0
            m *= i
            done = original_array[0..i]
            v += m * arr.select {|y| done.include?(y)}.rindex(x)
        }
        v
    end
permute(number)
# File lib/facets/core/enumerable/permute.rb, line 6
    def permute(number)
        arr = to_a
        out = arr[0..0]
        nextfactor = factor = 1
        arr.each_with_index {|x,i|
            case i
            when 0: next
            else
                nextfactor = factor * (i+1)
                out.insert(number % nextfactor / factor, x)
                factor = nextfactor
            end
        }
        out
    end
probability()

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

# File lib/facets/core/enumerable/probability.rb, line 10
  def probability
    probs = Hash.new(0.0)
    size = 0.0
    each do | e |
      probs[e] += 1.0
      size += 1.0
    end
    probs.keys.each { |e| probs[e] /= size }
    probs
  end
project(&block)
# File lib/facets/core/enumerable/project.rb, line 7
  def project(&block)
    self.map{|x| x.instance_eval(&block) }
  end
to_h( &blk )

Produces a hash from an Enumerable with index for keys.

  enu = 'a'..'b'
  enu.to_h  #=> { 0=>'a', 1=>'b' }

If a block is passed, the hash values will be set by calling the block with the enumerated element and it’s counter.

  enu = 'a'..'b'
  enu.to_h{ |e,i| e }  #=> { 0=>'a', 1=>'b' }

See also graph.

# File lib/facets/core/enumerable/to_h.rb, line 18
  def to_h( &blk )
    h = {}
    if block_given?
      each_with_index{ |e,i| h[i] = blk.call(e,i) }
    else
      each_with_index{ |e,i| h[i] = e }
    end
    h
  end
uniq_by( {|| ...}

Like uniq, 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/facets/core/enumerable/uniq_by.rb, line 12
  def uniq_by #:yield:
    h = {}; inject([]) {|a,x| h[yield(x)] ||= a << x}
  end
where(&block)
# File lib/facets/core/enumerable/where.rb, line 7
  def where(&block)
    self.select{|x| x.instance_eval(&block) }
  end