class Array

class NilClass

# Provide platform dependent null path.
#
# @standard
#   require 'facets/pathname'
#
# @author Daniel Burger
def to_path
  Pathname.null
end

end

Public Class Methods

zip(*arrays) click to toggle source

Class level rendition of Array#zip.

arrays - List of arrays to zip. [Array<Array>]

Example:

Array.zip([1,2],[3,4]]
#=> [[1,3],[2,4]]

Returns arranged array of arrays. [Array<Array>]

Returns an empty array if no arguments are given. [Array]

# File lib/core/facets/array/zip.rb, line 16
def self.zip(*arrays)
  return [] if arrays.empty?
  return arrays[0].zip(*arrays[1..-1])
end

Public Instance Methods

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/core/facets/array/before.rb, line 35
def after(value)
  return nil unless include? value
  self[(index(value).to_i + 1) % length]
end
arrange() click to toggle source

The `arrange` method produces appropriate ranges from the objects in the array.

Examples

[1,2,3,6,7,8].arrange  #=> [1..3, 6..8]

[10..15, 16..20, 21, 22].arrange  #=> [10..22]

Assumes inclusive ranges (ie. 1..4) and range.first <= range.last.

Works with integers, dates and strings. However, all the objects in the array must be of the same class.

CREDIT: monocle

# File lib/core/facets/array/arrange.rb, line 18
def arrange
              array = uniq.sort_by { |e| Range === e ? e.first : e }
              array.inject([]) do |c, value|
                      unless c.empty?
                              last = c.last
                              last_value    = (Range === last  ? last.last   : last)
                              current_value = (Range === value ? value.first : value)
                              if (last_value.succ <=> current_value) == -1
                                      c << value
                              else
                                      first  = (Range === last ? last.first : last)
                                      second = [Range === last ? last.last : last, Range === value ? value.last : value].max
                                      c[-1] = [first..second]
                                      c.flatten!
                              end
                      else
                              c << value
                      end
              end
      end
Also aliased as: rangify
average() click to toggle source

Calculate the average of an array of numbers

Examples

[].average #=> nil
[1, 2, 3].average #=> 2
[3, 12, 57, 85, 15, 89, 33, 7, 22, 54].average #=> 37.7
[1,[2,nil,[3]],nil,4].collapse  #=> [1,2,3,4]
# File lib/core/facets/array/average.rb, line 12
def average
  return nil if empty?
  self.reduce(:+)/length.to_f
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/core/facets/array/before.rb, line 17
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.

Examples

[1,[2,nil,[3]],nil,4].collapse  #=> [1,2,3,4]
# File lib/core/facets/array/collapse.rb, line 9
def collapse
  flatten.compact
end
collapse!() click to toggle source
# File lib/core/facets/array/collapse.rb, line 13
def collapse!
  flatten!.compact!
end
collisions(&block)

Deprecated: Alias for commonality.

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

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

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

persons.commonality { |person| person.last_name }

The method is similar to group_by which is a standard Ruby method as of 1.9. To get effectively the same results with group_by use `select{ |k,v| v.size > 1 }`.

[1, 2, 2, 3, 4, 4].group_by{ |e| e }.select{ |k,v| v.size > 1 }
#=> { 2 => [2, 2], 4 => [4, 4] }

Examples

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

["foo", "bar", "baz"].commonality { |str| str[0] }
#=> { 'b' => ["bar", "baz"] }

Returns [Hash] mapping common attribute to those elements.

CREDIT: Florian Gross

# File lib/core/facets/array/commonality.rb, line 29
def commonality(&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 result
end
Also aliased as: collisions
conjoin(*args) { |i, *slice(i,2)| ... } 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/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
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/core/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/core/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/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(pattern) click to toggle source

Divide on matching pattern.

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

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

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

CREDIT: Trans

# File lib/core/facets/array/divide.rb, line 16
def divide(pattern)
  memo = []
  memo.push [] unless pattern === first
  each do |obj|
    memo.push [] if pattern === obj
    memo.last << obj
  end
  memo
end
duplicates(min=2) click to toggle source

Return list of duplicate elements.

min - The minimum number of duplication necessary for inclusion. [Integer]

Examples:

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

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

CREDIT: Rebort Dober (current implementation) CREDIT: Thibaut Barrère

# File lib/core/facets/array/duplicates.rb, line 16
def duplicates(min=2)
  h = Hash.new( 0 )
  each {|i|
    h[i] += 1
  }
  h.delete_if{|_,v| v < min}.keys
end
each_overlap(slice_size, overlap) { |slice(i...i+slice_size)| ... } click to toggle source

Iterate over each slice where the last n values of a preceding slice overlap with the first n values of the following slice. The value of n is specified by the second `overlap` argument.

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

Returns nothing.

# File lib/core/facets/array/each_overlap.rb, line 13
def each_overlap(slice_size, overlap)
  if block_given?
                i = 0
                while i + slice_size <= length
                  yield slice(i...i+slice_size)
                  i += (slice_size - overlap)
                end
  else
    to_enum(:each_overlap, slice_size, overlap)
  end
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/core/facets/array/each_pair.rb, line 6
def each_pair #:yield:
  each_with_index {|e, i| yield(i,e) }
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/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
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/core/facets/array/extract_options.rb, line 23
def extract_options!
  if Hash === last && last.extractable_options?
    pop
  else
    {}
  end
end
from(index) click to toggle source

Returns elements from `index` until the end.

%w{W o r l d}.from(3)  #=> ["l", "d"]
%w{W o r l d}.from(9)  #=> []
# File lib/core/facets/array/from.rb, line 8
def from(index)
  return [] if index >= size
  self[index..-1]
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/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
intersection() click to toggle source

Returns the values in common for an array set (nil, single value/object, or range).

CREDIT: monocle

# File lib/core/facets/array/intersection.rb, line 7
def intersection
        array = uniq.sort_by { |e| Range === e ? e.first : e }
        array.inject() do |c, e|
                f = (Range === c ? c.last  : c)
                v = (Range === e ? e.first : e)
                case f <=> v
                when -1 then return nil
                when  0 then f
                else
                        if Range === e
                                v..([f, e.last].min)
                        else
                                v
                        end
                end
        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/core/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/core/facets/array/merge.rb, line 11
def merge!( other )
  self.replace(self.merge(other))
end
missing() click to toggle source

Determine the “holes” in the values of an array.

TODO: Better name?

Returns the missing elements in an array set.

CREDIT: monocle

# File lib/core/facets/array/missing.rb, line 13
    def missing
            missing, array = [], arrange
            i, length = 0, array.size - 1
            while i < length 
  x0 = array[i]
  x1 = array[i+1]
                    c = (Range === x0 ? x0.last  : x0)
                    n = (Range === x1 ? x1.first : x1)
                    missing << (
    c.succ.succ == n ? c.succ : ((c.succ)..(n.pred))
  )
                    i += 1
            end
return missing
    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 there 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/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
nonuniq() click to toggle source

Returns a list of non-unique elements.

Examples

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

CREDIT: Martin DeMello

# File lib/core/facets/array/nonuniq.rb, line 11
def nonuniq
  h1 = {}
  h2 = {}
  each {|i|
    h2[i] = true if h1[i]
    h1[i] = true
  }
  h2.keys
end
nonuniq!() click to toggle source

Same as `#nonuniq` but acts in place.

# File lib/core/facets/array/nonuniq.rb, line 23
def nonuniq!
  self.replace(self.nonuniq)
end
not_empty?() click to toggle source

Not empty?

[].not_empty?     #=> false
[1,2].not_empty?  #=> true
# File lib/core/facets/array/not_empty.rb, line 8
def not_empty?
  !empty?
end
object_state(data=nil) click to toggle source
# File lib/core/facets/object/object_state.rb, line 47
def object_state(data=nil)
  data ? replace(data) : dup
end
occur(n=nil) { || ... } click to toggle source

Returns a list of elements that occur n times.

If n is a Range then returns elements that occur a number of time within the range.

Examples

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

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

Returns [Array] of reoccurring elements.

CREDIT: Robert Dober

# File lib/core/facets/array/occur.rb, line 18
def occur(n=nil) #:yield:
  h = Hash.new(0)

  each do |i|
    h[i] += 1
  end

  case n
  when nil
    h.delete_if{ |_,v| ! yield(v) }.keys
  when Range
    h.delete_if{ |_,v| ! n.include?(v) }.keys
  else
    h.delete_if{|_,v| v != n}.keys
  end
end
Also aliased as: occurs
occurrence() { |e| ... } click to toggle source

Create a hash of each uniq element of the array and how many time each appears.

Examples

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

[2,2,3,4,4,4].occurrence{|i| i % 2}
#=> { 0 => 5, 1 => 1 }
# File lib/core/facets/array/occurrence.rb, line 14
def occurrence
  h = Hash.new(0)
  if block_given?
    each do |e|
      h[yield(e)] += 1
    end
  else
    each do |e|
      h[e] += 1
    end
  end
  h
end
occurs(n=nil)

Plural alias of occur.

Alias for: occur
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/core/facets/array/only.rb, line 18
def only
  unless size == 1
    raise IndexError, "not the only element of array"
  end
  first
end
only?() click to toggle source

Does this Array have only one element?

TODO: While clearly this goes along with the regular only method, the name doesn't seem quite right. Perhaps rename to lonely.

CREDIT: Lavir the Whiolet

# File lib/core/facets/array/only.rb, line 32
def only?
  size == 1
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/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
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/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(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/core/facets/array/pull.rb, line 14
def peek(i=0)
  i = -(i + 1)
  fetch(i)
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/core/facets/array/pull.rb, line 26
def poke(x, i=0)
  insert(i,x)
end
power_set() click to toggle source

@author Phrogz

# File lib/standard/facets/set.rb, line 24
def power_set
  if empty?
    [self]
  else
    subset  = dup
    value   = [ subset.pop ]
    subsubs = subset.power_set
    subsubs.concat( subsubs.map{ |subset| subset + value } )
  end
end
probability() click to toggle source

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

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

CREDIT: Brian Schröder

# File lib/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
rangify()
Alias for: arrange
recurse(*types) { |a| ... } 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/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
recurse!(&block) click to toggle source

In place form of recurse.

# File lib/core/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 given types.

By default the sub-types are passed through unaffected. Passing a block to recursively can be used to change this.

types - List of class types to recurse. [Array<Class>] block - Optional filter procedure to apply on each recursion.

Examples

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

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

Returns [Recursor].

# File lib/core/facets/array/recursively.rb, line 27
def recursively(*types, &block)
  Recursor.new(self, *types, &block)
end
reject_values(*values) click to toggle source

Non-destructive form of `Array#delete_values`. Unlike `delete_values` this method returns a new array.

values - List of array elements to reject.

Examples

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

Returns [Array]

CREDIT: Sean Mackesey

# File lib/core/facets/array/reject_values.rb, line 16
def reject_values(*values)
  reject { |x| values.include?(x) }
end
sd()
Alias for: standard_deviation
shelljoin() click to toggle source
# File lib/standard/facets/shellwords.rb, line 81
def shelljoin
  Shellwords.shelljoin(shellwords)
end
shellwords() click to toggle source

Convert an array into command line parameters. The array is accepted in the format of Ruby method arguments –ie. [arg1, arg2, …, hash]

# File lib/standard/facets/shellwords.rb, line 74
def shellwords
  opts, args = *flatten.partition{ |e| Hash === e }
  opts = opts.inject({}){ |m,h| m.update(h); m }
  opts.shellwords + args
end
splice(*args) click to toggle source

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

Examples

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

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

Returns [Array].

CREDIT: Trans

# File lib/core/facets/array/splice.rb, line 23
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.

Examples

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

Returns list of split-up arrays. [Array<Array>]

# File lib/core/facets/array/split.rb, line 13
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
squeeze!(*limited_to) click to toggle source

Destructive version of Enumerable#squeeze.

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

a = [1,2,2,3,3,2,1]
a.squeeze!(*[3])
a #=> [1,2,2,3,2,1]

Returns the receiver. [Array]

CREDIT: T. Yamada

# File lib/core/facets/array/squeeze.rb, line 19
def squeeze!(*limited_to)
  replace(squeeze(*limited_to))
end
standard_deviation() click to toggle source

Calculate the #standard_deviation of an array of numbers

Examples

[].standard_deviation #=> nil
[1, 2, 3].standard_deviation #=> 0.816496580927726
[96, 35, 72, 30, 75, 33, 68, 13, 49, 71].standard_deviation #=> 24.69331893448104
[36, -67, -17, 85, -46, -64, -23, -13, 89, -47].standard_deviation #=> 54.67183918618432
[60.7829, 31.2622, 20.626, 78.8907, 61.5328].standard_deviation #=> 21.428815505053002
# File lib/core/facets/array/standard_deviation.rb, line 15
def standard_deviation
  return nil if empty?
  Math.sqrt(variance)
end
Also aliased as: sd
step(n) { || ... } click to toggle source

Iterate over every nth element of an array.

r = []
[:a, :b, :c, :d].step(2) { |x| r << x }
r   #=> [:b, :d]

Without a block it returns an Enumerator.

[:a, :b, :c, :d].step(1).to_a   #=> [:a, :b, :c, :d]
[:a, :b, :c, :d].step(2).to_a   #=> [:b, :d]
[:a, :b, :c, :d].step(3).to_a   #=> [:c]
[:a, :b, :c, :d].step(5).to_a   #=> []

CREDIT: Ryan Duryea

# File lib/core/facets/array/step.rb, line 18
def step(n) #:yield:
  if block_given?
    ((n - 1)...size).step(n).each do |i|
      yield(fetch(i))
    end
  else
    Enumerator.new(size / n) do |y|
      ((n - 1)...self.size).step(n).each { |i| y << fetch(i) }  
    end
  end
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(2)  #=> [1,2,3]
[1,2,3,4,5].thru(4)  #=> [1,2,3,4,5]

[1,2,3,4,5].thru(0,2)  #=> [1,2,3]
[1,2,3,4,5].thru(2,4)  #=> [3,4,5]
# File lib/core/facets/array/from.rb, line 21
def thru(from, to=nil)
  from, to = 0, from unless to
  return [] if from >= size
  self[from..to]
end
to_b() click to toggle source

Boolean conversion for not empty?

# File lib/core/facets/boolean.rb, line 110
def to_b
  ! self.empty?
end
to_h() click to toggle source

Convert an associative array to a Hash.

Examples

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

Returns [Hash].

# File lib/core/facets/array/to_h.rb, line 12
def to_h
  h = {}
  each{ |(k,v)| h[k] = v }
  h
end
to_path() click to toggle source

Convert array to Pathname instance.

@standard

require 'facets/pathname'
# File lib/standard/facets/pathname/to_path.rb, line 24
def to_path
  Pathname.new(join('/'))
end
to_t() click to toggle source

Convert an array into a tuple.

# File lib/standard/facets/tuple.rb, line 276
def to_t
  Tuple.cast_from_array( self )
end
traverse(&block) click to toggle source

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

Examples

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.

Returns new array. [Array]

CREDIT: Trans

# File lib/core/facets/array/traverse.rb, line 19
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.

Examples:

h = ["A", "B", ["X", "Y"]]
h.traverse!{ |e| e.downcase }
h  #=> ["a", "b", ["x", "y"]]

Returns self. [Array]

CREDIT: Trans

# File lib/core/facets/array/traverse.rb, line 45
def traverse!(&block)
  replace(traverse(&block))
end
uniq_by!() { || ... } click to toggle source

Like uniq, but determines uniqueness based on a given block. As can be seen in the following examples, order is significant.

Examples

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

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

Returns [Array] of unique elements.

# File lib/core/facets/array/uniq_by.rb, line 18
def uniq_by! #:yield:
  h = {}
  replace( inject([]){|a,x| h[yield(x)] ||= a << x} )
end
unique_permutation(n=self.size) { |a| ... } click to toggle source

Enumerates permutation of Array. Unlike Array#permutation, there are no duplicates in generated permutations. Instead, elements must be comparable.

[1,1,2,2,3].unique_permutation(2).to_a
#=> [[1, 1], [1, 2], [1, 3], [2, 1], [2, 2], [2, 3], [3, 1], [3, 2]]
# Note: [1,1,2,2,3].permutation(2).to_a
#=> [[1, 1], [1, 2], [1, 2], [1, 3], [1, 1], [1, 2], [1, 2], [1, 3], [2, 1], [2, 1], [2, 2], [2, 3], [2, 1], [2, 1], [2, 2], [2, 3], [3, 1], [3, 1], [3, 2], [3, 2]]

CREDIT: T. Yamada

# File lib/core/facets/array/unique_permutation.rb, line 13
def unique_permutation(n=self.size)
  return to_enum(:unique_permutation,n) unless block_given?
  return if n<0||self.size<n
  a=self.sort # sort is O(nlogn), so I believe this is not so costly. (Also sort is not destructive)
  yield a[0,n]
  loop{
    a=a[0,n]+a[n..-1].reverse
    k=(a.size-2).downto(0).find{|i|a[i]<a[i+1]}
    break if !k
    l=(a.size-1).downto(k+1).find{|i|a[k]<a[i]}
    a[k],a[l]=a[l],a[k]
    a=a[0,k+1]+a[k+1..-1].reverse
    yield a[0,n]
  }
end
variance() click to toggle source

Calculate the variance of an array of numbers

Examples

[].variance #=> nil
[1, 2, 3].variance #=> 0.6666666666666666
[96, 35, 72, 30, 75, 33, 68, 13, 49, 71].variance #=> 609.76
[36, -67, -17, 85, -46, -64, -23, -13, 89, -47].variance #=> 2989.0099999999993
[60.7829, 31.2622, 20.626, 78.8907, 61.5328].variance #=> 459.1941339495999
# File lib/core/facets/array/variance.rb, line 15
def variance
  avg = average
  map {|n| (n - avg) ** 2 }.average
end