Class: Array

Inherits:
Object show all
Defined in:
lib/gorillib/array/wrap.rb,
lib/gorillib/string/human.rb,
lib/gorillib/array/hashify.rb,
lib/gorillib/array/deep_compact.rb,
lib/gorillib/array/compact_blank.rb,
lib/gorillib/model/serialization.rb,
lib/gorillib/array/extract_options.rb,
lib/gorillib/serialization/to_wire.rb,
lib/gorillib/array/simple_statistics.rb,
lib/gorillib/deprecated/array/random.rb,
lib/gorillib/deprecated/array/average.rb,
lib/gorillib/deprecated/array/sorted_median.rb,
lib/gorillib/deprecated/array/sorted_sample.rb,
lib/gorillib/deprecated/array/sorted_percentile.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.wrap(object) ⇒ Object

Wraps its argument in an array unless it is already an array (or array-like).

Specifically:

  • If the argument is +nil+ an empty list is returned.
  • Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
  • Otherwise, returns an array with the argument as its single element.

This method is similar in purpose to Kernel#Array, but there are some differences:

  • If the argument responds to +to_ary+ the method is invoked. Kernel#Array moves on to try +to_a+ if the returned value is +nil+, but Array.wrap returns such a +nil+ right away.
  • If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, Kernel#Array raises an exception, while Array.wrap does not, it just returns the value.
  • It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.

The last point is particularly worth comparing for some enumerables:

There's also a related idiom that uses the splat operator:

[*object]

which returns [nil] for +nil+, and calls to Array(object) otherwise.

Thus, in this case the behavior is different for +nil+, and the differences with Kernel#Array explained above apply to the rest of +object+s.

Examples:

nil: an empty list

Array.wrap(nil)       # => []

an array: itself

Array.wrap([1, 2, 3]) # => [1, 2, 3]

an atom: array of length 1

Array.wrap(0)         # => [0]

It does not molest hashes

Array(:foo => :bar)      # => [[:foo, :bar]]
Array.wrap(:foo => :bar) # => [{:foo => :bar}]

It does not do insane things to strings

Array("foo\nbar")        # => ["foo\n", "bar"], in Ruby 1.8
Array.wrap("foo\nbar")   # => ["foo\nbar"]


44
45
46
47
48
49
50
51
52
# File 'lib/gorillib/array/wrap.rb', line 44

def self.wrap(object)
  if object.nil?
    []
  elsif object.respond_to?(:to_ary)
    object.to_ary || [object]
  else
    [object]
  end
end

Instance Method Details

#at_fraction(fraction) ⇒ Object

Returns the element that fraction of the way along the indexes.

Examples:

halfway point:

[1,4,9,16,25].at_fraction(0.5)      #  9

note that indexes are rounded down:

[1,4,9,16,25].at_fraction(0.74999)  #  9
[1,4,9,16,25].at_fraction(0.75)     # 16

blank array:

[].at_fraction(0.1)       # nil

Returns:

  • the element that fraction of the way along the indexes

Raises:



26
27
28
29
30
# File 'lib/gorillib/array/simple_statistics.rb', line 26

def at_fraction(fraction)
  raise ArgumentError, "fraction should be between 0.0 and 1.0: got #{fraction.inspect}" unless (0.0 .. 1.0).include?(fraction)
  return nil if empty?
  self[ ((size - 1) * Float(fraction)).round ]
end

#averageObject

Return the average of my elements.

precondition: Each element must be convertible to a float.

Raises:



8
9
10
11
# File 'lib/gorillib/array/simple_statistics.rb', line 8

def average
  return nil if empty?
  inject(:+) / size.to_f
end

#compact_blankObject

remove all key-value pairs where the value is blank



7
8
9
# File 'lib/gorillib/array/compact_blank.rb', line 7

def compact_blank
  reject{|val| val.blank? }
end

#compact_blank!Object

Replace the array with its compact_blank'ed self



14
15
16
# File 'lib/gorillib/array/compact_blank.rb', line 14

def compact_blank!
  replace(compact_blank)
end

#deep_compact!Object

deep_compact! removes all 'blank?' elements in the array in place, recursively



8
9
10
11
12
13
# File 'lib/gorillib/array/deep_compact.rb', line 8

def deep_compact!
  self.map! do |val|
    val.deep_compact! if val.respond_to?(:deep_compact!)
    val unless val.blank?
  end.compact!
end

#extract_options!Object

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



22
23
24
25
26
27
28
# File 'lib/gorillib/array/extract_options.rb', line 22

def extract_options!
  if last.is_a?(Hash) && last.extractable_options?
    pop
  else
    {}
  end
end

#hashifyHash

Gets value of block on each element; constructs a hash of element-value pairs

Returns:

  • (Hash)

    hash of key-value pairs

Raises:



7
8
9
10
# File 'lib/gorillib/array/hashify.rb', line 7

def hashify
  raise ArgumentError, 'hashify requires a block' unless block_given?
  Hash[ self.map{|el| [el, yield(el)] } ]
end

#random_elementObject

Choose a random element from the array



5
6
7
8
# File 'lib/gorillib/deprecated/array/random.rb', line 5

def random_element
  warn "Deprecated; use built-in #sample instead"
  sample
end

#sorted_medianObject

Returns the middle element of odd-sized arrays. For even arrays, it will return one of the two middle elements. Precisely which is undefined, except that it will consistently return one or the other.



61
62
63
# File 'lib/gorillib/array/simple_statistics.rb', line 61

def sorted_median
  at_fraction(0.5)
end

#sorted_percentile(percentile) ⇒ Object

Returns the element at the position closest to the given percentile. For example, sorted_percentile 0.0 will return the first element and sorted_percentile 100.0 will return the last element.



73
74
75
# File 'lib/gorillib/array/simple_statistics.rb', line 73

def sorted_percentile(percentile)
  at_fraction(percentile / 100.0)
end

#sorted_sample(num) ⇒ Object

DEPRECATED -- use #uniq_nths(num) (#sample is already a method on Array, so this name is confusing)



9
10
11
# File 'lib/gorillib/deprecated/array/sorted_sample.rb', line 9

def sorted_sample(num)
  sorted_nths(num)
end

#take_nths(num) ⇒ Object

The array must be sorted for this to be useful.

Examples:

[1,4,9,16,25,36,49].take_nths(3)  # [4, 16, 36]
[ 4,9,  16,  36,49].take_nths(3)  # [4, 16, 36]
[1,4,9,16,25,36,49].take_nths(5)  # [1, 4, 16, 25, 36]

edge cases

[1,4,9,16,25,36,49].take_nths(99) # [1,4,9,16,25,36,49]
[1,4,9,16,25,36,49].take_nths(1)  # [16]
[1,4,9,16,25,36,49].take_nths(0)  # []
[].take_nths(3)                   # []

Returns:

  • the 1/nth, 2/nth, ... n/nth (last) elements in the array.



48
49
50
51
# File 'lib/gorillib/array/simple_statistics.rb', line 48

def take_nths(num)
  return [] if empty?
  (0 .. num-1).map{|step| at_fraction( (step + 0.5)/(num)) }.uniq
end

#to_sentence(options = {}) ⇒ Object

Converts the array to a comma-separated sentence where the last element is joined by the connector word. Options:

  • :words_connector - The sign or word used to join the elements in arrays with two or more elements (default: ", ")
  • :two_words_connector - The sign or word used to join the elements in arrays with two elements (default: " and ")
  • :last_word_connector - The sign or word used to join the last element in arrays with three or more elements (default: ", and ")


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/gorillib/string/human.rb', line 33

def to_sentence(options = {})
  default_words_connector     = ", "
  default_two_words_connector = " and "
  default_last_word_connector = ", and "
  options = { :words_connector => default_words_connector, :two_words_connector => default_two_words_connector, :last_word_connector => default_last_word_connector }.merge(options)

  case length
    when 0
      ""
    when 1
      self[0].to_s.dup
    when 2
      "#{self[0]}#{options[:two_words_connector]}#{self[1]}"
    else
      "#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
  end
end

#to_tsvObject



4
5
6
# File 'lib/gorillib/model/serialization.rb', line 4

def to_tsv
  to_wire.join("\t")
end

#to_wire(options = {}) ⇒ Object



35
36
37
# File 'lib/gorillib/serialization/to_wire.rb', line 35

def to_wire(options={})
  map{|item| item.respond_to?(:to_wire) ? item.to_wire : item }
end