Convert and array into a tuple.
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?. |
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 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
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
# 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
Inverse of delete_if.
[1,2,3].delete_unless{ |x| x < 2 } => [1,2]
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 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 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
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
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
# File lib/core/facets/kernel/object_state.rb, line 29 def object_state(data=nil) data ? replace(data) : dup end
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 def only unless size == 1 raise IndexError, "Array#only called on non-single-element array" end first end
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
# 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
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
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 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
# 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
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 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
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?
# 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
In place form of recursively.
# File lib/core/facets/array/recursively.rb, line 26 def recursively!(&block) replace(recursively(&block)) end
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 def rotate(n=1) self.dup.rotate!(n) end
Same as rotate, 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 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
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
# File lib/core/facets/array/splice.rb, line 17 def splice(*args) if args.size == 1 slice!(*args) else store(*args) end end
Boolean conversion for not empty?
# File lib/core/facets/boolean.rb, line 60 def to_b ! self.empty? end
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
# 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
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 def to_h_assoc h = {} each do |k,*v| h[k] = v end h end
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 }
# 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
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] }
# 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
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 def to_h_splat a = dup a << nil if a.size % 2 == 1 Hash[*a] end
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 44 def to_shellwords flags = (Hash===last ? pop : {}) flags = flags.to_shellwords flags + ' ' + self #join(" ") end
# 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