Class: Array

Class | Array
In: | lib/core/facets/array/combination.rb lib/core/facets/array/conjoin.rb lib/core/facets/array/delete_unless.rb lib/core/facets/array/delete_values.rb lib/core/facets/array/index.rb lib/core/facets/array/indexable.rb lib/core/facets/array/merge.rb lib/core/facets/array/not_empty.rb lib/core/facets/array/only.rb lib/core/facets/array/pad.rb lib/core/facets/array/permutation.rb lib/core/facets/array/product.rb lib/core/facets/array/recursively.rb lib/core/facets/array/rotate.rb lib/core/facets/array/select.rb lib/core/facets/array/splice.rb lib/core/facets/array/stackable.rb lib/core/facets/array/traverse.rb lib/core/facets/blank.rb lib/core/facets/boolean.rb lib/core/facets/kernel/object_state.rb lib/core/facets/string/contains.rb lib/core/facets/to_hash.rb lib/more/facets/random.rb lib/more/facets/set.rb lib/more/facets/shellwords.rb lib/more/facets/tuple.rb
Parent: | Object

Convert and array into a tuple.

### Methods

** combination conjoin delete_unless delete_values delete_values_at index merge! not_empty? object_state only pad pad! permutation power_set product recursively recursively! rotate rotate! select! splice to_b to_console to_h to_h_assoc to_h_auto to_h_flat to_h_multi to_h_splat to_shell to_shellwords to_t traverse traverse!

### Included Modules

Indexable Stackable Random

### External Aliases

shift | -> | first!
| Alias for shift, which removes and returns the first element in an array.
      a = ["a","y","z"]
      a.first!      #=> "a"
      p a           #=> ["y","z"]
CREDIT: Trans
pop | -> | last!
| Alias for pop, which removes and returns the last element in an array.
      a = [1,2]
      a.last! 3
      p a           #=> [1,2,3]
CREDIT: Trans
| | -> | merge
| Alias for `|`.
      [1,2].merge [2,3]  #=> [1,2,3]
[]= | -> | store
| Store a value at a givne index. Store is an alias for #[]=.
unshift | -> | poke
| "Put On Top". This is an alias for unshift which puts an object# on top of the stack. It is the converse of push.
      a=[1,2,3]
      a.poke(9)   #=> [9,1,2,3]
      a           #=> [9,1,2,3]
CREDIT: Trans
shift | -> | pull
| Alias for shift which removes an object off first slot of an array. This is the contrary of pop.
      a=[1,2,3]
      a.pull  #=> 1
      a       #=> [2,3]
CREDIT: Trans
empty? | -> | blank?
include? | -> | contains?
| Alias for include?.

### Public Instance methods

**(*enums)

Alias for product

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

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/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

conjoin(*args) {|i, *slice(i,2)| ...}

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

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

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

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

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

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

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

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

CREDIT: Trans

[Source]

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

        sep = []

        if block_given?
          (size - 1).times do |i|
            sep << yield(i, *slice(i,2))
          end
        else
          options   = (Hash===args.last) ? args.pop : {}
          separator = args.shift || ""
          options[-1] = args.shift unless args.empty?

          sep = [separator] * (size - 1)

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

          options[-1] ||= " and "

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

delete_unless(&block)

Inverse of delete_if.

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

CREDIT: Daniel Schierbeck

[Source]

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

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

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/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

index(obj=nil, &block)

Allows index to accept a block.

OVERRIDE! This is one of the bery few core overrides in Facets.

[Source]

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

merge!( other )

In place merge.

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

CREDIT: Trans

[Source]

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

not_empty?()

Not empty?

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

[Source]

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

object_state(data=nil)

[Source]

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

only()

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

      [5].only      # -> 5
      [1,2,3].only  # -> IndexError
      [].only       # -> IndexError

CREDIT: Gavin Sinclair, Noah Gibbs

[Source]

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

pad(len, val=nil)

Pad an array with a given `value` upto 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/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)

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/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

permutation(n=size) {|[]| ...}

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.

CREDIT: Shin-ichiro Hara

[Source]

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

power_set()

[Source]

    # File lib/more/facets/set.rb, line 16
      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

product(*enums)

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/core/facets/array/product.rb, line 13
        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

recursively() {|a| ...}

Apply a block to hash, and recursively apply that block to each subhash.

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

TODO: Can this be generalized in Enumerbale?

[Source]

    # File lib/core/facets/array/recursively.rb, line 12
      def recursively(&block)
        a = inject([]) do |array, value|
          if value.is_a?(Array)
            array << value.recursively(&block)
          else
            array << value
          end
          array
        end
        yield a
      end

recursively!(&block)

In place form of recursively.

[Source]

    # File lib/core/facets/array/recursively.rb, line 26
      def recursively!(&block)
        replace(recursively(&block))
      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]

CREDIT: Florian Gross, Thomas Sawyer

[Source]

    # File lib/core/facets/array/rotate.rb, line 16
      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]

CREDIT: Florian Gross, Thomas Sawyer

[Source]

    # File lib/core/facets/array/rotate.rb, line 28
      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]

CREDIT: Gavin Sinclair

[Source]

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

splice(*args)

Splice acts a combination of slice! and store. If two arguments are given it calls store. If a single argument is give 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/core/facets/array/splice.rb, line 17
      def splice(*args)
        if args.size == 1
          slice!(*args)
        else
          store(*args)
        end
      end

to_b()

Boolean conversion for not empty?

[Source]

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

to_console()

Alias for to_shell

to_h(mode=nil)

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 CREDIT: Trans

[Source]

    # File lib/core/facets/to_hash.rb, line 52
      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

to_h_assoc()

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/core/facets/to_hash.rb, line 156
      def to_h_assoc
        h = {}
        each do |k,*v|
          h[k] = v
        end
        h
      end

to_h_auto()

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 }

[Source]

    # File lib/core/facets/to_hash.rb, line 92
      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

to_h_flat()

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/core/facets/to_hash.rb, line 134
      def to_h_flat
        a = flatten
        a << nil if a.size % 2 == 1
        Hash[*a]
      end

to_h_multi()

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/core/facets/to_hash.rb, line 176
      def to_h_multi
        h = {}
        each do |k,*v|
          h[k] ||= []
          h[k].concat(v)
        end
        h
      end

to_h_splat()

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/core/facets/to_hash.rb, line 121
      def to_h_splat
        a = dup
        a << nil if a.size % 2 == 1
        Hash[*a]
      end

to_shell()

[Source]

    # File lib/more/facets/shellwords.rb, line 50
      def to_shell
        to_shellwords.join(' ')
      end

to_shellwords()

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

[Source]

    # File lib/more/facets/shellwords.rb, line 44
      def to_shellwords
        flags = (Hash===last ? pop : {})
        flags = flags.to_shellwords
        flags + ' ' + self #join(" ")
      end

to_t()

[Source]

    # File lib/more/facets/tuple.rb, line 320
      def to_t
        Tuple.cast_from_array( self )
      end

traverse() {|item| ...}

[Source]

    # File lib/core/facets/array/traverse.rb, line 5
      def traverse(&block)
        map do |item|
          if item.is_a?(self.class)
            item.traverse(&block)
          else
            yield item
          end
        end
      end

traverse!(&block)

[Source]

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

[Validate]