### Home Classes Methods

### In Files

- lib/facets/object/object_state.rb
- lib/facets/array/each_value.rb
- lib/facets/array/select.rb
- lib/facets/array/store.rb
- lib/facets/array/traverse.rb
- lib/facets/array/each_pair.rb
- lib/facets/array/median.rb
- lib/facets/array/recurse.rb
- lib/facets/array/merge.rb
- lib/facets/array/product.rb
- lib/facets/array/collapse.rb
- lib/facets/array/split.rb
- lib/facets/array/not_empty.rb
- lib/facets/array/commonality.rb
- lib/facets/array/before.rb
- lib/facets/array/mode.rb
- lib/facets/array/combination.rb
- lib/facets/array/permutation.rb
- lib/facets/array/conjoin.rb
- lib/facets/array/contains.rb
- lib/facets/array/extract_options.rb
- lib/facets/array/op_pow.rb
- lib/facets/array/delete_unless.rb
- lib/facets/array/divide.rb
- lib/facets/array/index.rb
- lib/facets/array/rotate.rb
- lib/facets/array/only.rb
- lib/facets/array/recursively.rb
- lib/facets/array/splice.rb
- lib/facets/array/pull.rb
- lib/facets/array/delete_values.rb
- lib/facets/array/pad.rb
- lib/facets/array/from.rb
- lib/facets/array/entropy.rb
- lib/facets/array/indexable.rb
- lib/facets/array/uniq_by.rb
- lib/facets/boolean.rb
- lib/facets/enumerable/count.rb
- lib/facets/kernel/blank.rb

### Parent

Object

### Methods

- #**
- #after
- #before
- #collapse
- #collisions
- #combination
- #commonality
- #conjoin
- #delete_unless
- #delete_values
- #delete_values_at
- #divide
- #each_pair
- #entropy
- #extract_options!
- #from
- #ideal_entropy
- #index
- #median
- #merge!
- #mode
- #not_empty?
- #object_state
- #only
- #pad
- #pad!
- #peek
- #permutation
- #poke
- #product
- #recurse
- #recurse!
- #recursively
- #rotate
- #rotate!
- #select!
- #splice
- #split
- #thru
- #to_b
- #traverse
- #traverse!
- #uniq_by!

### Included Modules

- Indexable

### Files

- README.rdoc

### Class/Module Index

Quicksearch

- Lazy
- Lazy::Future
- Lazy::Promise
- Lazy::Promise::DIVERGES
- Lazy::PromiseSafe
- Enumerable
- Enumerable::Recursor
- Method
- Method::Composition
- Module
- Module::InstanceFunction
- Array
- Binding
- Class
- Comparable
- Denumerable
- Denumerator
- Dir
- Enumerator
- Exception
- Facets
- FalseClass
- File
- FileTest
- Fixnum
- Float
- Functor
- Hash
- Indexable
- Instance
- Integer
- Kernel
- MatchData
- NA
- NilClass
- Numeric
- Object
- ObjectSpace
- Proc
- Process
- Range
- Regexp
- String
- Struct
- Symbol
- Time
- TrueClass
- UnboundMethod

No matching classes.

# Array

### Public Instance Methods

**(*enums) click to toggle source

Array#** is an alias for Array#product.

NOTE: This method is not a common core extension and is not loaded automatically when using `require 'facets'`.

@uncommon

    require 'facets/array/op_pow'

Alias for: product
after(value) click to toggle source

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

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

before(value) click to toggle source

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

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

collapse() click to toggle source

Simplify an array by flattening it then compacting it.

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

    # File lib/facets/array/collapse.rb, line 7
    def collapse
      flatten.compact
    end

collisions(&block) click to toggle source
Alias for: commonality
combination(k=2) click to toggle source

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

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

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

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

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

Also aliased as: collisions
conjoin(*args, &block) click to toggle source

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

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

delete_unless(&block) click to toggle source

Inverse of delete_if.

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

CREDIT: Daniel Schierbeck

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

delete_values(*values) click to toggle source

Delete multiple values from array.

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

CREDIT: Trans

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

delete_values_at(*selectors) click to toggle source

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

    # File lib/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(pattern) click to toggle source

Divide on matching pattern.

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

CREDIT: Trans

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

each_pair() click to toggle source

Iterate over index and value. The intention of this method is to provide polymorphism with Hash.

    # File lib/facets/array/each_pair.rb, line 6
    def each_pair #:yield:
      i = -1
      each_value do |x|
        yield(i+=1, x)
      end
    end

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.

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

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

CREDIT: Derek

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

extract_options!() click to toggle source

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}

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

from(i) click to toggle source

Returns last n elements.

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

    # File lib/facets/array/from.rb, line 7
    def from(i)
      return self if i >= size
      self[i, size - i]
    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/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

index(obj=nil, &block) click to toggle source

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.

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

median(offset=0) click to toggle source

Determines the sorted middle element.

    a = %w{a a b b c c c}
    a.median     #=> "b"

When there are an even number of elements, the greater of the two middle elements is given.

    a = %w{a a b b c c c d}
    a.median     #=> "c"

An offset can be supplied to get an element relative to the middle.

    a = %w{a a b b c c c d}
    a.median(-1) #=> "b"

The the array is empty, `nil` is returned.

@return [Object] sorted middle element

    # File lib/facets/array/median.rb, line 23
    def median(offset=0)
      return nil if self.size == 0

      tmp = self.sort
      mid = (tmp.size / 2).to_i + offset

      tmp[mid]
    end

merge!( other ) click to toggle source

In place merge.

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

CREDIT: Trans

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

mode() click to toggle source

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.

@author Robert Klemme

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

not_empty?() click to toggle source

Not empty?

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

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

object_state(data=nil) click to toggle source

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

only() click to toggle source

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

    # File lib/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(len, val=nil) click to toggle source

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

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

pad!(len, val=nil) click to toggle source

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

    # File lib/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(i=0) click to toggle source

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.

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

permutation(n=size) click to toggle source

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

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

poke(x, i=0) click to toggle source

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.

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

product(*enums) click to toggle source

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

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

Also aliased as: **
recurse(*types, &block) click to toggle source

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

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

recurse!(&block) click to toggle source

In place form of recurse.

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

recursively(*types, &block) click to toggle source

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 ?

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

rotate(n=1) click to toggle source

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

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

rotate!(n=1) click to toggle source

Same as rotate, but acts in place.

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

CREDIT: Florian Gross, Thomas Sawyer

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

select!() click to toggle source

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

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

splice(*args) click to toggle source

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

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

split(pattern) click to toggle source

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

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

thru(from, to=nil) click to toggle source

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]

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

to_b() click to toggle source

Boolean conversion for not empty?

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

traverse(&block) click to toggle source

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

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

traverse!(&block) click to toggle source

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

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

uniq_by!() click to toggle source

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.

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

[Validate]

Generated with the Darkfish Rdoc Generator 2.