Methods
Public Instance methods
/(len)

Partition an array into parts of given length.

# File lib/facets/core/array/op_mod.rb, line 8
  def / len
    inject([]) do |ary, x|
      ary << [] if [*ary.last].nitems % len == 0
      ary.last << x
      ary
    end
  end
[](*args)

Modifies #[] to also accept an array of indexes.

  a = ['a','b','c','d','e','f']

  a[[1]]      #=> ['b']
  a[[1,1]]    #=> ['b','b']
  a[[1,-1]]   #=> ['b','f']
  a[[0,2,4]]  #=> ['a','c','e']
# File lib/facets/core/array/op_fetch.rb, line 13
  def [](*args)
    return values_at(*args.at(0)) if Array === args.at(0)
    return slice(*args)
  end
[]=(*args)

Modifies #[]= to accept an array of indexes for assignment.

  a = ['a','b','c','d']

  a[[1,-1]] = ['m','n']    #=> ['m','n']
  a                        #=> ['a','m','c','n']
This method is also aliased as store
# File lib/facets/core/array/op_store.rb, line 12
  def []=(*args)
    if Array === args.at(0)
      idx,vals = args.at(0),args.at(1)
      idx.each_with_index{ |a,i| store(a,vals.at(i)) }
      return values_at( *idx )
    else
      return store(*args)
    end
  end
at_rand()

Return a random element of the array.

  [1, 2, 3, 4].at_rand           #=> 2
  [1, 2, 3, 4].at_rand           #=> 4
# File lib/facets/core/array/at_rand.rb, line 8
  def at_rand
    self.at( rand( size ) )
  end
at_rand!()

Same as at_rand, but acts in place removing a random element from the array.

  a = [1,2,3,4]
  a.at_rand!       #=> 2
  a                #=> [1,3,4]
# File lib/facets/core/array/at_rand.rb, line 19
  def at_rand!
    return delete_at( Kernel.rand( size ) )
  end
body()

Returns an array of the first element upto, but not including, the last element.

  [1,2,3].body  #=> [1,2]
# File lib/facets/core/array/head.rb, line 38
  def body
    slice(0,length-1)
  end
delete_unless(&block)
# File lib/facets/core/array/delete_unless.rb, line 7
  def delete_unless (&block)
    delete_if { |element| not block.call(element) }
  end
delete_values(*values)

Delete multiple values from array.

  a = [1,2,3,4]
  a.delete_values(1,2)   #=> [1,2]
  a                      #=> [3,4]
# File lib/facets/core/array/delete_values.rb, line 9
  def delete_values(*values)
    d = []
    values.each{ |v| d << delete(v) }
    d
  end
delete_values_at(*selectors)

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]
# File lib/facets/core/array/delete_values_at.rb, line 14
  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
each_by(n=nil, &yld)

Alias for each_slice

each_combination(k=2) {|s.values_at(*idx)| ...}

Yields the block to each unique combination of n elements.

  a = %w|a b c d|
  a.each_combination(3) do |c|
    p c
  end

produces

  ["a", "b", "c"]
  ["a", "b", "d"]
  ["a", "c", "d"]
  ["b", "c", "d"]
# File lib/facets/core/enumerable/each_combination.rb, line 18
  def each_combination(k=2)
    s = self.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
  end
each_slice(n=nil, &yld)

Iterates over n elements at a time. If n is not given then the arity of the block determines the slicing quantity.

  [1, 2, 3, 4].each_slice(2){ |a,b| ... }

This is a specialized version Enumerable#each_slice but optimized specifically for Array.

This method is also aliased as each_by
# File lib/facets/core/enumerable/each_slice.rb, line 50
  def each_slice(n=nil, &yld)
    n = yld.arity.abs unless n
    i=0
    while i < self.length
      yld.call(*self.slice(i,n))
      i+=n
    end
  end
each_unique_pair(&yld)

Processes each unique pair (of indices, not value) in the array by yielding them to the supplied block.

  a = [1,2,3,4]
  a.each_unique_pair{ |a,b| puts a+','+b }

produces

  1,2
  1,3
  1,4
  2,3
  2,4
  3,4

This does not guarantee the uniqueness of values. For example:

  a = [1,2,1]
  a.each_unique_pair{ |a,b| puts a+','+b }

prduces

  1,2
  1,1
  2,1

This is equivalent to each_combination(2){ … }.

# File lib/facets/core/enumerable/each_unique_pair.rb, line 33
  def each_unique_pair(&yld)
    self.each_combination(2,&yld)
    #s = self.to_a
    #self.each_with_index{ |a,i|
    #  self[(i+1)..-1].each{ |b| yield a,b }
    #}
  end
every!()

In place version of every.

# File lib/facets/core/enumerable/every.rb, line 25
  def every!
    Functor.new do |op,*args|
      self.replace( self.collect{ |a| a.send(op,*args) } )
    end
  end
first=(x)

Change the first element.

  a = ["a","y","z"]
  a.first = "x"
  p a           #=> ["x","y","z"]
# File lib/facets/core/array/first.rb, line 11
  def first=(x)
    self[0] = x
  end
foot()

Like last, returning the last element in an array.

  [1,2,3].foot  #=> [3]
# File lib/facets/core/array/head.rb, line 26
  def foot
    slice(-1,1)
  end
head()

Like first but returns the first element in a new array.

  [1,2,3].head  #=> [1]
# File lib/facets/core/array/head.rb, line 9
  def head
    slice(0,1)
  end
join_sentence()
# File lib/facets/core/array/join_sentence.rb, line 4
  def join_sentence
    case length
    when 0: ""
    when 1: self[0]
    else [self[0..-2].join(", "), self[-1]].join(" and ")
    end
  end
last=(x)

Change the last element.

  a = [1,2,5]
  a.last = 3
  p a           #=> [1,2,3]
# File lib/facets/core/array/first.rb, line 30
  def last=(x)
    self[-1] = x
  end
last_index()

Returns the last index of the array. Returns nil is array has no elements.

  [1,2,3,4,5].last_index  #=> 4
# File lib/facets/core/array/last_index.rb, line 9
  def last_index
    return nil if self.length == 0
    self.length - 1
  end
merge!( other )
# File lib/facets/core/array/merge.rb, line 6
  def merge!( other )
    self.replace( self | other )
  end
mid(offset=0)

Returns the middle element of an array, or the element offset from middle if the parameter is given. Even-sized arrays, not having an exact middle, return the middle-right element.

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

In other words, If there are an even number of elements the higher-indexed of the two center elements is indexed as orgin (0).

# File lib/facets/core/array/mid.rb, line 17
  def mid(offset=0)
    self.at( (self.length / 2) + offset )
  end
middle()

Returns the middle element(s) of an array. Even-sized arrays, not having an exact middle, returns a two-element array of the two middle elements.

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

In contrast to mid which utilizes an offset.

# File lib/facets/core/array/middle.rb, line 12
  def middle
    if size % 2 == 0
      [ at((size/2)-1), at(size/2) ]
    else
      at(size/2)
    end
  end
pick(n=nil)

Similar to at_rand, but will return an array of randomly picked exclusive elements if given a number.

# File lib/facets/core/array/pick.rb, line 6
  def pick(n=nil)
    if n
      a = self.dup
      a.pick!(n)
    else
      at( Kernel.rand( size ) )
    end
  end
pick!(n=nil)

Similar to at_rand!, but given a number will return an array of exclusive elements.

# File lib/facets/core/array/pick.rb, line 17
  def pick!(n=nil)
    if n
      if n > self.size
        r = self.dup
        self.replace([])
        r
      else
        r = []
        n.times { r << delete_at( Kernel.rand( size ) ) }
        r
      end
    else
      delete_at( Kernel.rand( size ) )
    end
  end
pos(i)

Returns the positive ordinal index given a cardinal position, 1 to n or -n to -1.

  [1,2,3,4,5].pos(1)   #=> 0
  [1,2,3,4,5].pos(-1)  #=> 4
# File lib/facets/core/array/pos.rb, line 8
  def pos(i)
    if i > 0
      return i - 1
    else
      self.length + i
    end
  end
rand_index()
# File lib/facets/core/array/rand_index.rb, line 2
  def rand_index
    rand( size )
  end
rand_subset( number=nil, exclusive=true )

Returns a random subset of an Array. If a number of elements is specified then returns that number of elements, otherwise returns a random number of elements upto the size of the Array.

By defualt the returned values are exclusive of each other, but if exclusive is set to false, the same values can be choosen more than once.

When exclusive is true (the default) and the number given is greater than the size of the array, then all values are returned.

  [1, 2, 3, 4].rand_subset(1)        #=> [2]
  [1, 2, 3, 4].rand_subset(4)        #=> [2, 1, 3, 4]
  [1, 2, 3, 4].rand_subset           #=> [1, 3, 4]
  [1, 2, 3, 4].rand_subset           #=> [2, 3]
# File lib/facets/core/array/rand_subset.rb, line 22
  def rand_subset( number=nil, exclusive=true )
    number = rand( size ) unless number
    number = number.to_int
    #return self.dup if (number >= size and exlusive)
    return sort_by{rand}.slice(0,number) if exclusive
    ri =[]; number.times { |n| ri << rand( size ) }
    return values_at(*ri)
  end
range(a=nil,z=nil)

Returns the index range between two elements. If no elements are given, returns the range from first to last.

  ['a','b','c','d'].range            #=> 0..3
  ['a','b','c','d'].range('b','d')   #=> 1..2
# File lib/facets/core/array/range.rb, line 12
  def range(a=nil,z=nil)
    if !a
      0..self.length-1
    else
      index(a)..index(z)
    end
  end
rotate(n=1)

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

  [1,2,3].rotate      #=> [3,1,2]
  [3,1,2].rotate      #=> [2,3,1]
  [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)  #=> [2,3,1]
# File lib/facets/core/array/rotate.rb, line 15
  def rotate(n=1)
    self.dup.rotate!(n)
  end
rotate!(n=1)

Same as rotate, but acts in place.

  a = [1,2,3]
  a.rotate!
  a  #=> [3,1,2]
# File lib/facets/core/array/rotate.rb, line 25
  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!( {|| ...}

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]
# File lib/facets/core/array/select.rb, line 10
  def select!  # :yield:
    reject!{ |e| not yield(e) }
  end
shuffle()

Randomize the order of an array.

  [1,2,3,4].shuffle  #=> [2,4,1,3]
# File lib/facets/core/array/shuffle.rb, line 11
  def shuffle
    dup.shuffle!
    #sort_by{Kernel.rand}
  end
shuffle!()

As with shuffle but modifies the array in place. The algorithm used here is known as a Fisher-Yates shuffle.

  a = [1,2,3,4]
  a.shuffle!
  a  #=> [2,4,1,3]
# File lib/facets/core/array/shuffle.rb, line 23
  def shuffle!
    s = size
    each_index do |j|
      i = Kernel.rand(s-j)
      #self[j], self[j+i] = self[j+i], self[j]
      tmp = self[j]
      self[j] = self[j+i]
      self[j+i] = tmp
    end
    self
  end
store(*args)

Alias for #[]=

tail()

Returns an array from second element to last element.

  [1,2,3].tail  #=> [2,3]
# File lib/facets/core/array/head.rb, line 17
  def tail
    slice(1,length-1)
  end
thru( from, to )

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]
# File lib/facets/core/array/thru.rb, line 7
  def thru( from, to )
    a = []
    i = from
    while i <= to
      a << self.at(i)
      i += 1
    end
    a
  end
to_b()

Boolean conversion for not empty?

# File lib/facets/core/array/to_b.rb, line 5
  def to_b
    ! self.empty?
  end
to_h(arrayed=nil)

Converts a two-element associative array into a hash.

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

If arrayed is set it will maintain trailing arrays.

  a = [ [:a,1,2], [:b,3] ]
  a.to_h(true)  #=> { :a=>[1,2], :b=>[3] }

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

  array1.zip(array2).to_h
# File lib/facets/core/array/to_h.rb, line 19
  def to_h(arrayed=nil)
    unless arrayed
      Hash[*self.flatten]
    else
      h = {}
      each{ |e| h[e.first] = e.slice(1..-1) }
      h
    end
  end
to_hash()

Converts an array into a hash.

This methd is just like Enumerable#to_h. But has been moved in order to accomodate associtiave arrays. We use to_hash becasue an Array is, in essence, a hash, just with a restricted set of keys and maintained order.

  a = [ :a, :b, :c ]
  a.to_hash  #=> { 0=>:a, 1=>:b, 2=>:c }
# File lib/facets/core/array/to_hash.rb, line 18
  def to_hash
    h = {}
    each_with_index{ |e,i| h[i] = e }
    h
  end
unzip(level)
# File lib/facets/core/array/unzip.rb, line 3
  def unzip(level)
    res = Array.new(level, [])
    (0...size).each {|i|
      res[i % level] += [self[i]]
    }
    res
  end