Class Array
In: lib/facets/core/facets/enumerable/count.rb
lib/facets/core/facets/array/nonuniq.rb
lib/facets/core/facets/array/recurse.rb
lib/facets/core/facets/array/only.rb
lib/facets/core/facets/array/split.rb
lib/facets/core/facets/array/mode.rb
lib/facets/core/facets/array/indexable.rb
lib/facets/core/facets/array/traverse.rb
lib/facets/core/facets/array/entropy.rb
lib/facets/core/facets/array/index.rb
lib/facets/core/facets/array/delete_values.rb
lib/facets/core/facets/array/store.rb
lib/facets/core/facets/array/uniq_by.rb
lib/facets/core/facets/array/pad.rb
lib/facets/core/facets/array/pull.rb
lib/facets/core/facets/array/commonality.rb
lib/facets/core/facets/array/merge.rb
lib/facets/core/facets/array/probability.rb
lib/facets/core/facets/array/combination.rb
lib/facets/core/facets/array/not_empty.rb
lib/facets/core/facets/array/before.rb
lib/facets/core/facets/array/conjoin.rb
lib/facets/core/facets/array/permutation.rb
lib/facets/core/facets/array/collapse.rb
lib/facets/core/facets/array/product.rb
lib/facets/core/facets/array/extract_options.rb
lib/facets/core/facets/array/contains.rb
lib/facets/core/facets/array/splice.rb
lib/facets/core/facets/array/delete_unless.rb
lib/facets/core/facets/array/from.rb
lib/facets/core/facets/array/rotate.rb
lib/facets/core/facets/array/select.rb
lib/facets/core/facets/array/recursively.rb
lib/facets/core/facets/array/divide.rb
lib/facets/core/facets/object/object_state.rb
lib/facets/core/facets/kernel/blank.rb
lib/facets/core/facets/to_hash.rb
lib/facets/core/facets/boolean.rb
Parent: Object

Methods

Included Modules

Indexable

External Aliases

shift -> first!
  Alias for shift, which removes and returns the first element in an array.
  a = ["a","y","z"]
  a.first!      #=> "a"
  a             #=> ["y","z"]

CREDIT: Trans

pop -> last!
  Alias for pop, which removes and returns the last element in an array.
  a = [1,2,3]
  a.last!       #=> 3
  a             #=> [1,2]

CREDIT: Trans

[]= -> store
  Store a value at a given index. Store is an alias for #[]=.
  a = []
  a.store(1, "A")
  a[1] #=> "A"
shift -> pull
  Alias for shift which removes an object off first slot of an array. This is the opposite of pop.
| -> merge
  Alias for |.
  [1,2].merge([2,3])  #=> [1,2,3]
include? -> contains?
  Alias for include?.
empty? -> blank?

Public Instance methods

Returns the value after the given value. The value before the last is the first. Returns nil if the given value is not in the array.

Examples

  sequence = ['a', 'b', 'c']
  sequence.after('a')           #=> 'b'
  sequence.after('b')           #=> 'c'
  sequence.after('c')           #=> 'a'
  sequence.after('d')           #=> nil

CREDIT: Tyler Rick

[Source]

# File lib/facets/core/facets/array/before.rb, line 33
  def after(value)
    return nil unless include? value
    self[(index(value).to_i + 1) % length]
  end

Returns the value previous to the given value. The value previous to the first is the last. Returns nil if the given value is not in the array.

Examples

  sequence = ['a', 'b', 'c']
  sequence.before('a')           #=> 'c'
  sequence.before('b')           #=> 'a'
  sequence.before('c')           #=> 'b'
  sequence.before('d')           #=> nil

CREDIT: Tyler Rick

[Source]

# File lib/facets/core/facets/array/before.rb, line 16
  def before(value)
    return nil unless include? value
    self[(index(value).to_i - 1) % length]
  end

Simplify an array by flattening it then compacting it.

  [1,[2,nil,[3]],nil,4].collapse  #=> [1,2,3,4]

[Source]

# File lib/facets/core/facets/array/collapse.rb, line 7
  def collapse
    flatten.compact
  end
collisions(&block)

Alias for commonality

Yields the block to each unique combination of n elements.

  a = %w|a b c d|
  a.combination(3)

produces

  [["a", "b", "c"],
   ["a", "b", "d"],
   ["a", "c", "d"],
   ["b", "c", "d"]]

CREDIT: Florian Gross

[Source]

# File lib/facets/core/facets/array/combination.rb, line 21
    def combination(k=2)
      if block_given?
        s = to_a
        n = s.size
        return unless (1..n) === k
        idx = (0...k).to_a
        loop do
          yield s.values_at(*idx)
          i = k - 1
          i -= 1 while idx[i] == n - k + i
          break if i < 0
          idx[i] += 1
          (i + 1 ... k).each {|j| idx[j] = idx[i] + j - i}
        end
      else
        to_enum(:combination, k)
      end
    end

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"] }

This can be useful, for instance, in determining all persons that share their last name with another person …

  persons.collisions { |person| person.last_name }

CREDIT: Florian Gross

[Source]

# File lib/facets/core/facets/array/commonality.rb, line 19
  def commonality(&block)
    had_no_block = !block
    block ||= lambda { |item| item }
    result = Hash.new { |hash, key| hash[key] = Array.new }
    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

This is more advanced form of join. It allows for fine control of separators.

NOTE: The old version used to default its separator to ", " and default the terminating separator to " and ". This is no longer the case. You must specifically provide these parameters.

If no paramters are given, it acts like join but will a space separator.

  [1,2,3].conjoin
  #=> "1 2 3"

Use comma+space and ‘and’ on tail.

  [1,2,3].conjoin(', ', ' and ')
  #=> "1, 2 and 3"

Use comma+space and ‘or’ on tail using :last option.

  [1,2,3].conjoin(', ', :last => ' or ')
  #=> "1, 2 or 3"

Use semicolon+space and ampersand on tail using index.

  [1,2,3].conjoin('; ', -1 => ' & ')
  #=> "1; 2 & 3"

Can take a block to determine separator.

  [1,2,3,4].conjoin{ |i, a, b| i % 2 == 0 ? '.' : '-' }
  #=> "1.2-3.4"

This makes very esoteric transformation possible.

  [1,1,2,2].conjoin{ |i, a, b| a == b ? '=' : ' != ' }
  #=> "1=1 != 2=2"

  [1,2,3,4].conjoin{ |i, x, y| "<#{i} #{x} #{y}>" }
  #=> "1<0 1 2>2<1 2 3>3<2 3 4>4"

There are also spacing options. Providing the :space option pads the separators.

  [1,2,3].conjoin(',', '&', :space=>2)
  #=> "1  ,  2  &  3"

And the :spacer option can set an alternate spacing string.

  [1,2,3].conjoin('|', '>', :space=>2, :spacer=>'-')
  #=> "1--|--2-->--3"

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/conjoin.rb, line 57
  def conjoin(*args, &block)
    return first.to_s if size < 2

    options = (Hash===args.last) ? args.pop : {}

    spacing = options.delete(:space)  || 0
    spacer  = options.delete(:spacer) || " "
    space   = spacer * spacing.to_i

    sep = []

    if block_given?
      (size - 1).times do |i|
        sep << space + yield(i, *slice(i,2)) + space
      end
    else
      separator   = args.shift || " "
      options[-1] = args.shift if args.first

      options[0]  = options.delete(:first) if options.key?(:first)
      options[-1] = options.delete(:last)  if options.key?(:last)

      separator = space + separator + space

      sep = [separator] * (size - 1)

      options.each{|i, s| sep[i] = space + s + space}
    end
    zip(sep).join
  end

Inverse of delete_if.

  [1,2,3].delete_unless{ |x| x < 2 }
  #=> [1]

CREDIT: Daniel Schierbeck

[Source]

# File lib/facets/core/facets/array/delete_unless.rb, line 10
  def delete_unless(&block)
    delete_if { |element| not block.call(element) }
  end

Delete multiple values from array.

  a = [1,2,3,4]
  a.delete_values(1,2)   #=> [1,2]
  a                      #=> [3,4]

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/delete_values.rb, line 11
  def delete_values(*values)
    d = []
    values.each{ |v| d << delete(v) }
    d
  end

Delete multiple values from array given indexes or index range.

  a = [1,2,3,4]
  a.delete_values_at(1,2)   #=> [2,3]
  a                         #=> [1,4]
  a = [1,2,3,4]
  a.delete_values_at(0..2)  #=> [1,2,3]
  a                         #=> [4]

NOTE: It would be nice to see delete_at incorporate this funcitonaility.

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/delete_values.rb, line 32
  def delete_values_at(*selectors)
    idx = []
    selectors.each{ |i|
      case i
      when Range
        idx.concat( i.to_a )
      else
        idx << i.to_i
      end
    }
    idx.uniq!
    dvals = values_at(*idx)
    idx = (0...size).to_a - idx
    self.replace( values_at(*idx) )
    return dvals
  end

Divide on matching pattern.

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

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/divide.rb, line 10
  def divide(pattern)
    memo = []
    each do |obj|
      memo.push [] if pattern === obj
      memo.last << obj
    end
    memo
  end
duplicates()

Alias for nonuniq

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.

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

  ("%.3f" % e)  #=> "2.128"

CREDIT: Derek

[Source]

# File lib/facets/core/facets/array/entropy.rb, line 16
  def entropy
    arr = self
    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

Extracts options from a set of arguments. Removes and returns the last element in the array if it‘s a hash, otherwise returns a blank hash.

  def options(*args)
    args.extract_options!
  end

  options(1, 2)           # => {}
  options(1, 2, :a => :b) # => {:a=>:b}

[Source]

# File lib/facets/core/facets/array/extract_options.rb, line 23
  def extract_options!
    if Hash === last && last.extractable_options?
      pop
    else
      {}
    end
  end

Returns last n elements.

  %w{W o r l d}.from(3)  #=> %w{l d}

[Source]

# File lib/facets/core/facets/array/from.rb, line 7
  def from(i)
    return self if i >= size
    self[i, size - i]
  end

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

[Source]

# File lib/facets/core/facets/array/entropy.rb, line 32
  def ideal_entropy
    arr = self
    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

Allows index to accept a block.

  ['a', 'b', 'c'].index{ |x| x.upcase == 'C' } #=> 2

IMPORTANT: This is one of the few core overrides in Facets.

[Source]

# File lib/facets/core/facets/array/index.rb, line 12
    def index(obj=nil, &block)
      if block_given?
        _facets_index(find(&block))
      else
        _facets_index(obj)
      end
    end

In place merge.

  a = [1,2]
  a.merge! [2,3]
  a #=> [1,2,3]

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/merge.rb, line 11
  def merge!( other )
    self.replace(self.merge(other))
  end

In Statistics mode is the value that occurs most frequently in a given set of data. This method returns an array in case their is a tie.

  [:a, :b, :c, :b, :d].mode  #=> [:b]
  [:a, :b, :c, :b, :a].mode  #=> [:a, :b]

Returns an Array of most common elements.

CREDIT: Robert Klemme

[Source]

# File lib/facets/core/facets/array/mode.rb, line 14
  def mode
    max = 0
    c = Hash.new 0
    each {|x| cc = c[x] += 1; max = cc if cc > max}
    c.select {|k,v| v == max}.map {|k,v| k}
  end

Returns a list of non-unique elements

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

CREDIT: Martin DeMello

[Source]

# File lib/facets/core/facets/array/nonuniq.rb, line 9
  def nonuniq
    h1 = {}
    h2 = {}
    each {|i|
      h2[i] = true if h1[i]
      h1[i] = true
    }
    h2.keys
  end

[Source]

# File lib/facets/core/facets/array/nonuniq.rb, line 20
  def nonuniq!
    h1 = {}
    h2 = {}
    each {|i|
      h2[i] = true if h1[i]
      h1[i] = true
    }
    self.replace(h2.keys)
  end

Not empty?

  [].not_empty?     #=> false
  [1,2].not_empty?  #=> true

[Source]

# File lib/facets/core/facets/array/not_empty.rb, line 8
  def not_empty?
    !empty?
  end

[Source]

# File lib/facets/core/facets/object/object_state.rb, line 47
  def object_state(data=nil)
    data ? replace(data) : dup
  end

Returns the only element in the array. Raises an IndexError if the array‘s size is not 1.

  [5].only      # => 5

  expect IndexError do
    [1,2,3].only
  end

  expect IndexError do
    [].only
  end

CREDIT: Gavin Sinclair, Noah Gibbs

[Source]

# File lib/facets/core/facets/array/only.rb, line 18
  def only
    unless size == 1
      raise IndexError, "Array#only called on non-single-element array"
    end
    first
  end

Pad an array with a given value up to a given length.

  [0,1,2].pad(6,"a")  #=> [0,1,2,"a","a","a"]

If length is a negative number padding will be added to the beginning of the array.

  [0,1,2].pad(-6,"a")  #=> ["a","a","a",0,1,2]

CREDIT: Richard Laugesen

[Source]

# File lib/facets/core/facets/array/pad.rb, line 14
  def pad(len, val=nil)
    return dup if self.size >= len.abs
    if len < 0
      Array.new((len+size).abs,val) + self
    else
      self + Array.new(len-size,val)
    end
  end

Like pad but changes the array in place.

   a = [0,1,2]
   a.pad!(6,"x")
   a  #=> [0,1,2,"x","x","x"]

CREDIT: Richard Laugesen

[Source]

# File lib/facets/core/facets/array/pad.rb, line 31
  def pad!(len, val=nil)
    return self if self.size >= len.abs
    if len < 0
      replace Array.new((len+size).abs,val) + self
    else
      concat Array.new(len-size,val)
    end
  end

Peek at the top of the stack (the end of the array).

  a = [1, 2, 3]
  a.peek          #=> 3
  a               #=> [1, 2, 3]

Or provide an index to inspect the array from back to front.

[Source]

# File lib/facets/core/facets/array/pull.rb, line 14
  def peek(i=0)
    i = -(i + 1)
    fetch(i)
  end

Permutation provids the possible orders of an enumerable. Each is indexed by a permutation number. The maximum number of arrangements is the factorial of the size of the array.

   [1,2].permutation(2).to_a #=> [[1,2], [2,1]]

CREDIT: Shin-ichiro Hara

[Source]

# File lib/facets/core/facets/array/permutation.rb, line 13
    def permutation(n=size)
      if size < n or n < 0
      elsif n == 0
        yield([])
      else
        self[1..-1].permutation(n - 1) do |x|
          (0...n).each do |i|
            yield(x[0...i] + [first] + x[i..-1])
          end
        end
        self[1..-1].permutation(n) do |x|
          yield(x)
        end
      end
    end

Put an object on the bottom of the stack (front of the array).

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

Or supply an index and poke works like insert.

[Source]

# File lib/facets/core/facets/array/pull.rb, line 26
  def poke(x, i=0)
    insert(i,x)
  end

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

  [:a, :b, :c, :c].probability  #=> {:a=> 0.25, :b=>0.25, :c=>0.5}

CREDIT: Brian Schröder

[Source]

# File lib/facets/core/facets/array/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

Provides the cartesian product of two or more arrays.

  a = [1,2].product([4,5])
  a  #=> [[1, 4],[1, 5],[2, 4],[2, 5]]

CREDIT: Thomas Hafner

[Source]

# File lib/facets/core/facets/array/product.rb, line 12
    def product(*enums)
      enums.unshift self
      result = [[]]
      while [] != enums
        t, result = result, []
        b, *enums = enums
        t.each do |a|
          b.each do |n|
            result << a + [n]
          end
        end
      end
      result
    end

Apply a block to array, and recursively apply that block to each sub-array or types.

  arr = ["a", ["b", "c", nil], nil]
  arr.recurse{ |a| a.compact! }
  #=> ["a", ["b", "c"]]

[Source]

# File lib/facets/core/facets/array/recurse.rb, line 10
  def recurse(*types, &block)
    types = [self.class] if types.empty?
    a = inject([]) do |array, value|
      case value
      when *types
        array << value.recurse(*types, &block)
      else
        array << value
      end
      array
    end
    yield a
  end

In place form of recurse.

[Source]

# File lib/facets/core/facets/array/recurse.rb, line 25
  def recurse!(&block)
    replace(recurse(&block))
  end

Apply a method to array, and recursively apply that method to each sub-array or types.

  arr = ["a", ["b", "c"]]
  arr.recursively.map{ |v| v.to_sym }
  #=> [:a, [:b, :c]]

By default the sub-types are passed thru uneffected. Passing a block to recursively changes this.

  arr = ["a", ["b", "c"]]
  arr.recursively{ |a| a.reverse }.map{ |v| v.to_sym }
  #=> [:a, [:c, :b]]

TODO: Return Enumerator if no yld block is given ?

[Source]

# File lib/facets/core/facets/array/recursively.rb, line 21
  def recursively(*types, &block)
    Recursor.new(self, *types, &block)
  end

Rotates an array‘s elements from back to front n times.

  [1,2,3].rotate      #=> [2,3,1]
  [2,3,1].rotate      #=> [3,1,2]
  [3,1,2].rotate      #=> [1,2,3]

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

A negative parameter reverses the order from front to back.

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

CREDIT: Florian Gross, Thomas Sawyer

[Source]

# File lib/facets/core/facets/array/rotate.rb, line 19
    def rotate(n=1)
      self.dup.rotate!(n)
    end

Same as rotate, but acts in place.

  a = [1,2,3]
  a.rotate!
  a  #=> [2,3,1]

CREDIT: Florian Gross, Thomas Sawyer

[Source]

# File lib/facets/core/facets/array/rotate.rb, line 35
    def rotate!(n=1)
      n = n.to_int
      return self if (n == 0 or self.empty?)
      if n < 0
        n.abs.times{ self.unshift( self.pop ) }
      else
        n.abs.times{ self.push( self.shift ) }
      end
      self
    end

As with select but modifies the Array in place.

  a = [1,2,3,4,5,6,7,8,9,10]
  a.select!{ |e| e % 2 == 0 }
  a  #=> [2,4,6,8,10]

CREDIT: Gavin Sinclair

[Source]

# File lib/facets/core/facets/array/select.rb, line 13
    def select!  # :yield:
      reject!{ |e| not yield(e) }
    end

Splice acts a combination of slice! and store. If two arguments are given it calls store. If a single argument is given it calls slice!.

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

  a = [1,2,3]
  a.splice(1,4)  #=> 4
  a              #=>[1,4,3]

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/splice.rb, line 19
  def splice(*args)
    if args.size == 1
      slice!(*args)
    else
      store(*args)
    end
  end

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

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

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/split.rb, line 10
  def split(pattern)
    memo = []
    sect = []
    each do |obj|
      if pattern === obj
        memo << sect
        sect = []
      else
        sect << obj
      end
    end
    memo << sect
    memo.pop while memo.last == []
    memo
  end

Fetch values from a start index thru an end index.

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

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

[Source]

# File lib/facets/core/facets/array/from.rb, line 20
  def thru(from, to=nil)
    from, to = 0, from unless to
    to = size - 1 if to >= size
    a = []
    i = from
    while i <= to
      a << self[i]
      i += 1
    end
    a
  end

Boolean conversion for not empty?

[Source]

# File lib/facets/core/facets/boolean.rb, line 110
  def to_b
    ! self.empty?
  end

Converts an array into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason to_h examines at the array being converted and then dispatches the conversion to the most sutiable specialized function. There are three possiblities for this.

If the array is a collection of perfect pairs, like that which Hash#to_a generates, then conversion is handled by to_h_flat.

  a = [ [:a,1], [:b,2] ]
  a.to_h  #=> { :a=>1, :b=>2 }

If the array contains only arrays, but are not perfect pairs, then to_h_multi is called.

  a = [ [:a,1,2], [:b,2], [:c], [:d] ]
  a.to_h  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If the array contians objects other then arrays then the to_h_splat method is called.

  a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
  a.to_h  #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }

Finally, a particular dispatch can be forced by specifying the mode of conversion, eg. +:multi+, +:splat+, +:flat+, +:assoc+, etc.

Setting mode to true is the same as setting it +:multi+. This has been left in for backward compatability.

NOTE: The use of a values parameter has been deprecated because that functionality is as simple as …

  array1.zip(array2).to_h

CREDIT: Robert Klemme, Trans

[Source]

# File lib/facets/core/facets/to_hash.rb, line 51
  def to_h(mode=nil)
    case mode
    when :splat
      return to_h_splat
    when :flat
      return to_h_flat
    when :multi, true
      return to_h_multi
    when :assoc
      return to_h_assoc
    else
      return to_h_auto
    end
  end

When a mixed or multi-element accociative array is used, the result is as follows:

  a = [ [:a,1,2], [:b,2], [:c], :d ]
  a.to_h  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If the first entry of any subelements are the same, then the value will be set to the last occuring value.

  a = [ :x, [:x], [:x,1,2], [:x,3], [:x,4] ]
  a.to_h_assoc  #=> { :x=>[4] }

[Source]

# File lib/facets/core/facets/to_hash.rb, line 157
  def to_h_assoc
    h = {}
    each do |k,*v| 
      h[k] = v
    end
    h
  end

Converts an array into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason to_h examines at the array being converted and then dispatches the conversion to the most sutiable specialized function. There are three possiblities for this.

If the array is a collection of perfect pairs, like that which Hash#to_a generates, then conversion is handled by to_h_flat.

  a = [ [:a,1], [:b,2] ]
  a.to_h_auto  #=> { :a=>1, :b=>2 }

If the array contains only arrays, but are not perfect pairs, then to_h_multi is called.

  a = [ [:a,1,2], [:b,2], [:c], [:d] ]
  a.to_h_auto  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If the array contians objects other then arrays then the to_h_splat method is called.

  a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
  a.to_h_auto  #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil }

[Source]

# File lib/facets/core/facets/to_hash.rb, line 91
  def to_h_auto
    pairs = true
    mixed = false

    each do |e|
      case e
      when Array
        pairs = false if e.size > 2
      else
        mixed = true
      end
    end

    if mixed
      to_h_splat
    elsif pairs
      to_h_flat
    else
      to_h_multi
    end
  end

This is equivalent to Hash, but it will pad the array with a nil object if there are not an even number of elements.

  a = [:a,1,[:b,2,:c]]
  a.to_h_flat  #=> { :a=>1, :b=>2, :c=>nil }

[Source]

# File lib/facets/core/facets/to_hash.rb, line 133
  def to_h_flat
    a = flatten
    a << nil if a.size % 2 == 1
    Hash[*a]
  end

When a mixed or multi-element accociative array is used, the result is as follows:

  a = [ [:a,1,2], [:b,2], [:c], :d ]
  a.to_h  #=> { :a=>[1,2], :b=>[2], :c=>[], :d=>[] }

If the first entry of the subelements is the same, then the values will be merged using concat.

  a = [ [:a,1,2], [:a,3], [:a,4], [:a], :a ]
  a.to_h_multi  #=> { :a=>[1,2,3,4] }

[Source]

# File lib/facets/core/facets/to_hash.rb, line 177
  def to_h_multi
    h = {}
    each do |k,*v| 
      h[k] ||= []
      h[k].concat(v)
    end
    h
  end

This is equivalent to Hash[*array], but it will pad the array with a nil object if there are not an even number of elements.

  a = [:a,1,:b,2,:c]
  a.to_h_splat  #=> { :a=>1, :b=>2, :c=>nil }

[Source]

# File lib/facets/core/facets/to_hash.rb, line 120
  def to_h_splat
    a = dup
    a << nil if a.size % 2 == 1
    Hash[*a]
  end

Returns a new array created by traversing the array and its sub-arrays, executing the given block on the elements.

  h = ["A", "B", ["X", "Y"]]

  g = h.traverse{ |e| e.downcase }

  g  #=> ["a", "b", ["x", "y"]]

This is the same as recursive.map and will likely be deprecated in the future because of it.

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/traverse.rb, line 16
  def traverse(&block)
    if block_given?
      map do |e|
        if e.respond_to?(:to_ary)
          e.to_ary.traverse(&block)
        else
          block.call(e)
        end
      end
    else
      to_enum(:traverse)
    end
  end

Like recursive_map, but will change the array in place.

  h = ["A", "B", ["X", "Y"]]

  h.traverse!{ |e| e.downcase }

  h  #=> ["a", "b", ["x", "y"]]

CREDIT: Trans

[Source]

# File lib/facets/core/facets/array/traverse.rb, line 39
  def traverse!(&block)
    replace(traverse(&block))
  end

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

  a = (-5..5).to_a
  a.uniq_by!{ |i| i*i }
  a #=> [-5, -4, -3, -2, -1, 0]

As can be seen in the example, order is significant.

[Source]

# File lib/facets/core/facets/array/uniq_by.rb, line 10
  def uniq_by! #:yield:
    h = {}
    replace( inject([]){|a,x| h[yield(x)] ||= a << x} )
  end

[Validate]