Parent

Namespace

Included Modules

Array

Convert and array into a tuple.

Public Instance Methods

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/core/facets/enumerable/collapse.rb, line 7
7:   def collapse
8:     flatten.compact
9:   end
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/core/facets/array/combination.rb, line 21
21:     def combination(k=2)
22:       if block_given?
23:         s = to_a
24:         n = s.size
25:         return unless (1..n) === k
26:         idx = (0...k).to_a
27:         loop do
28:           yield s.values_at(*idx)
29:           i = k - 1
30:           i -= 1 while idx[i] == n - k + i
31:           break if i < 0
32:           idx[i] += 1
33:           (i + 1 ... k).each {|j| idx[j] = idx[i] + j - i}
34:         end
35:       else
36:         to_enum(:combination, k)
37:       end
38:     end
conjoin(*args, &block) click to toggle source

This is more advanced form of #. 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.

  [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

    # File lib/core/facets/array/conjoin.rb, line 30
30:   def conjoin(*args, &block)
31:     return first.to_s if size < 2
32: 
33:     sep = []
34: 
35:     if block_given?
36:       (size - 1).times do |i|
37:         sep << yield(i, *slice(i,2))
38:       end
39:     else
40:       options   = (Hash===args.last) ? args.pop : {}
41:       separator = args.shift || ""
42:       options[1] = args.shift unless args.empty?
43: 
44:       sep = [separator] * (size - 1)
45: 
46:       if options.key?(:last)
47:         options[1] = options.delete(:last)
48:       end
49: 
50:       options[1] ||= " and "
51: 
52:       options.each{|i, s| sep[i] = s}
53:     end
54:     zip(sep).join
55:   end
delete_unless(&block) click to toggle source

Inverse of #.

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

CREDIT: Daniel Schierbeck

    # File lib/core/facets/array/delete_unless.rb, line 10
10:   def delete_unless(&block)
11:     delete_if { |element| not block.call(element) }
12:   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
11:   def delete_values(*values)
12:     d = []
13:     values.each{ |v| d << delete(v) }
14:     d
15:   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 # incorporate this funcitonaility.

CREDIT: Trans

    # File lib/core/facets/array/delete_values.rb, line 32
32:   def delete_values_at(*selectors)
33:     idx = []
34:     selectors.each{ |i|
35:       case i
36:       when Range
37:         idx.concat( i.to_a )
38:       else
39:         idx << i.to_i
40:       end
41:     }
42:     idx.uniq!
43:     dvals = values_at(*idx)
44:     idx = (0...size).to_a - idx
45:     self.replace( values_at(*idx) )
46:     return dvals
47:   end
index(obj=nil, &block) click to toggle source

Allows # to accept a block.

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

    # File lib/core/facets/array/index.rb, line 14
14:     def index(obj=nil, &block)
15:       if block_given?
16:         _facets_index(find(&block))
17:       else
18:         _facets_index(obj)
19:       end
20:     end
merge!( other ) click to toggle source

In place #.

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

CREDIT: Trans

    # File lib/core/facets/array/merge.rb, line 11
11:   def merge!( other )
12:     self.replace(self.merge(other))
13:   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
 8:   def not_empty?
 9:     !empty?
10:   end
object_state(data=nil) click to toggle source
    # File lib/core/facets/kernel/object_state.rb, line 31
31:   def object_state(data=nil)
32:     data ? replace(data) : dup
33:   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
  [1,2,3].only  # -> IndexError
  [].only       # -> IndexError

CREDIT: Gavin Sinclair, Noah Gibbs

    # File lib/core/facets/array/only.rb, line 12
12:   def only
13:     unless size == 1
14:       raise IndexError, "Array#only called on non-single-element array"
15:     end
16:     first
17:   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
14:   def pad(len, val=nil)
15:     return dup if self.size >= len.abs
16:     if len < 0
17:       Array.new((len+size).abs,val) + self
18:     else
19:       self + Array.new(len-size,val)
20:     end
21:   end
pad!(len, val=nil) click to toggle source

Like # 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
31:   def pad!(len, val=nil)
32:     return self if self.size >= len.abs
33:     if len < 0
34:       replace Array.new((len+size).abs,val) + self
35:     else
36:       concat Array.new(len-size,val)
37:     end
38:   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.

CREDIT: Shin-ichiro Hara

    # File lib/core/facets/array/permutation.rb, line 11
11:     def permutation(n=size)
12:       if size < n or n < 0
13:       elsif n == 0
14:         yield([])
15:       else
16:         self[1..1].permutation(n - 1) do |x|
17:           (0...n).each do |i|
18:             yield(x[0...i] + [first] + x[i..1])
19:           end
20:         end
21:         self[1..1].permutation(n) do |x|
22:           yield(x)
23:         end
24:       end
25:     end
power_set() click to toggle source
    # File lib/more/facets/set.rb, line 16
16:   def power_set
17:     if empty?
18:       [self]
19:     else
20:       subset  = dup
21:       value   = [ subset.pop ]
22:       subsubs = subset.power_set
23:       subsubs.concat( subsubs.map{ |subset| subset + value } )
24:     end
25:   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/core/facets/array/product.rb, line 13
13:     def product(*enums)
14:       enums.unshift self
15:       result = [[]]
16:       while [] != enums
17:         t, result = result, []
18:         b, *enums = enums
19:         t.each do |a|
20:           b.each do |n|
21:             result << a + [n]
22:           end
23:         end
24:       end
25:       result
26:     end
recursive(opts={}, &block) click to toggle source

Apply a block to array, and recursively apply that block to each subarray.

  arr = ["a", ["b", "c", nil], nil]
  arr.recursively{|a| a.compact! }
  => ["a", ["b", "c"]]
    # File lib/core/facets/array/recursive.rb, line 12
12:   def recursive(opts={}, &block)
13:     if block
14:       a = inject([]) do |array, value|
15:         if value.is_a?(Array)
16:           array << value.recursive(&block)
17:         else
18:           array << value
19:         end
20:         array
21:       end
22:       yield a
23:     else
24:       Recursor.new(self, opts)
25:     end
26:   end
recursive!(&block) click to toggle source

In place form of #.

    # File lib/core/facets/array/recursive.rb, line 30
30:   def recursive!(&block)
31:     r = recursive(&block)
32:     raise TypeError unless Array === r
33:     replace(r)
34:   end
recursively(&block) click to toggle source

Apply a block to array, and recursively apply that block to each subarray.

  arr = ["a", ["b", "c", nil], nil]
  arr.recursively{|a| a.compact! }
  => ["a", ["b", "c"]]
    # File lib/core/facets/array/recursively.rb, line 10
10:   def recursively(&block)
11:     warn "Use #recusive instead of #recursively for future versions"
12:     a = inject([]) do |array, value|
13:       if value.is_a?(Array)
14:         array << value.recursively(&block)
15:       else
16:         array << value
17:       end
18:       array
19:     end
20:     yield a
21:   end
recursively!(&block) click to toggle source

In place form of #.

    # File lib/core/facets/array/recursively.rb, line 25
25:   def recursively!(&block)
26:     replace(recursively(&block))
27:   end
rotate(n=1) click to toggle source

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

    # File lib/core/facets/array/rotate.rb, line 16
16:   def rotate(n=1)
17:     self.dup.rotate!(n)
18:   end
rotate!(n=1) click to toggle source

Same as #, but acts in place.

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

CREDIT: Florian Gross, Thomas Sawyer

    # File lib/core/facets/array/rotate.rb, line 28
28:   def rotate!(n=1)
29:     n = n.to_int
30:     return self if (n == 0 or self.empty?)
31:     if n > 0
32:       n.abs.times{ self.unshift( self.pop ) }
33:     else
34:       n.abs.times{ self.push( self.shift ) }
35:     end
36:     self
37:   end
select!() click to toggle source

As with # 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/core/facets/array/select.rb, line 11
11:   def select!  # :yield:
12:     reject!{ |e| not yield(e) }
13:   end
shelljoin() click to toggle source
    # File lib/more/facets/shellwords.rb, line 28
28:   def shelljoin
29:     Shellwords.shelljoin(shellwords)
30:   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/more/facets/shellwords.rb, line 22
22:   def shellwords
23:     opts, args = *flatten.partition{ |e| Hash === e }
24:     opts = opts.inject({}){ |m,h| m.update(h); m }
25:     opts.shellwords + args
26:   end
splice(*args) click to toggle source

Splice acts a combination of # and #. If two arguments are given it calls #. 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/core/facets/array/splice.rb, line 17
17:   def splice(*args)
18:     if args.size == 1
19:       slice!(*args)
20:     else
21:       store(*args)
22:     end
23:   end
to_b() click to toggle source

Boolean conversion for not empty?

     # File lib/core/facets/boolean.rb, line 132
132:   def to_b
133:     ! self.empty?
134:   end
to_h(mode=nil) click to toggle source

Converts an array into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason # 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 #.

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

If the array contains only arrays, but are not perfect pairs, then # 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 # 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

    # File lib/core/facets/to_hash.rb, line 52
52:   def to_h(mode=nil)
53:     case mode
54:     when :splat
55:       return to_h_splat
56:     when :flat
57:       return to_h_flat
58:     when :multi, true
59:       return to_h_multi
60:     when :assoc
61:       return to_h_assoc
62:     else
63:       return to_h_auto
64:     end
65:   end
to_h_assoc() click to toggle source

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 }
     # File lib/core/facets/to_hash.rb, line 156
156:   def to_h_assoc
157:     h = {}
158:     each do |k,*v| 
159:       h[k] = v
160:     end
161:     h
162:   end
to_h_auto() click to toggle source

Converts an array into a hash. Converting an array into a hash is not a one-to-one conversion, for this reason # 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 #.

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

If the array contains only arrays, but are not perfect pairs, then # 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 # method is called.

  a = [ [:a,1,2], 2, :b, [:c,3], 9 ]
  a.to_h  #=> { [:a,1,2]=>2, :b=>[:c,3], 9=>nil } 
     # File lib/core/facets/to_hash.rb, line 92
 92:   def to_h_auto
 93:     pairs = true
 94:     mixed = false
 95: 
 96:     each do |e|
 97:       case e
 98:       when Array
 99:         pairs = false if e.size > 2
100:       else
101:         mixed = true
102:       end
103:     end
104: 
105:     if mixed
106:       to_h_splat
107:     elsif pairs
108:       to_h_flat
109:     else
110:       to_h_multi
111:     end
112:   end
to_h_flat() click to toggle source

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 }
     # File lib/core/facets/to_hash.rb, line 134
134:   def to_h_flat
135:     a = flatten
136:     a << nil if a.size % 2 == 1
137:     Hash[*a]
138:   end
to_h_multi() click to toggle source

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

  a = [ [:a,1,2], [:a,3], [:a,4], [:a], :a ]
  a.to_h_multi  #=> { :a=>[1,2,3,4] }
     # File lib/core/facets/to_hash.rb, line 176
176:   def to_h_multi
177:     h = {}
178:     each do |k,*v| 
179:       h[k] ||= []
180:       h[k].concat(v)
181:     end
182:     h
183:   end
to_h_splat() click to toggle source

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 }
     # File lib/core/facets/to_hash.rb, line 121
121:   def to_h_splat
122:     a = dup
123:     a << nil if a.size % 2 == 1
124:     Hash[*a]
125:   end
to_t() click to toggle source
     # File lib/more/facets/tuple.rb, line 320
320:   def to_t
321:     Tuple.cast_from_array( self )
322:   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/core/facets/array/traverse.rb, line 17
17:   def traverse(&block)
18:     if block_given?
19:       map do |e|
20:         if e.respond_to?(:to_ary)
21:           e.to_ary.traverse(&block)
22:         else
23:           block.call(e)
24:         end
25:       end
26:     else
27:       to_enum(:traverse)
28:     end
29:   end
traverse!(&block) click to toggle source

Like #, but will change the array in place.

    # File lib/core/facets/array/traverse.rb, line 34
34:   def traverse!(&block)
35:     replace(traverse(&block))
36:   end
uniq_by!() click to toggle source

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

  (-5..5).to_a.uniq_by {|i| i*i }

produces

  [-5, -4, -3, -2, -1, 0]
    # File lib/core/facets/array/uniq_by.rb, line 13
13:   def uniq_by! #:yield:
14:     h = {}; replace(inject([]){|a,x| h[yield(x)] ||= a << x})
15:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.