Class: Array

Inherits:
Object show all
Includes:
Nuggets::Array::BlankMixin, Nuggets::Array::BoostMixin, Nuggets::Array::CorrelationMixin, Nuggets::Array::ExtractOptionsMixin, Nuggets::Array::FlushMixin, Nuggets::Array::HashifyMixin, Nuggets::Array::HistogramMixin, Nuggets::Array::InterpolateMixin, Nuggets::Array::LimitMixin, Nuggets::Array::MeanMixin, Nuggets::Array::MedianMixin, Nuggets::Array::ModeMixin, Nuggets::Array::RegressionMixin, Nuggets::Array::RuniqMixin, Nuggets::Array::StandardDeviationMixin, Nuggets::Array::VarianceMixin
Defined in:
lib/nuggets/array/only.rb,
lib/nuggets/array/mean.rb,
lib/nuggets/array/mode.rb,
lib/nuggets/array/rand.rb,
lib/nuggets/array/boost.rb,
lib/nuggets/array/flush.rb,
lib/nuggets/array/limit.rb,
lib/nuggets/array/runiq.rb,
lib/nuggets/array/format.rb,
lib/nuggets/array/median.rb,
lib/nuggets/object/blank.rb,
lib/nuggets/array/hashify.rb,
lib/nuggets/array/shuffle.rb,
lib/nuggets/array/to_hash.rb,
lib/nuggets/array/in_order.rb,
lib/nuggets/array/monotone.rb,
lib/nuggets/array/variance.rb,
lib/nuggets/dotted_decimal.rb,
lib/nuggets/array/histogram.rb,
lib/nuggets/array/regression.rb,
lib/nuggets/array/combination.rb,
lib/nuggets/array/correlation.rb,
lib/nuggets/array/interpolate.rb,
lib/nuggets/array/flatten_once.rb,
lib/nuggets/array/extract_options.rb,
lib/nuggets/array/standard_deviation.rb

Overview

#

nuggets – Extending Ruby #

#

Copyright © 2007-2011 Jens Wille #

#

Authors: #

Jens Wille <[email protected]>                                       #
                                                                        #

nuggets is free software; you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the Free # Software Foundation; either version 3 of the License, or (at your option) # any later version. #

#

nuggets is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for # more details. #

#

You should have received a copy of the GNU Affero General Public License # along with nuggets. If not, see <www.gnu.org/licenses/>. #

#

++

Constant Summary

Constants included from Nuggets::Array::HistogramMixin

Nuggets::Array::HistogramMixin::FORMATS

Instance Method Summary collapse

Methods included from Nuggets::Array::StandardDeviationMixin

included, #standard_deviation

Methods included from Nuggets::Array::ExtractOptionsMixin

#extract_options, #extract_options!

Methods included from Nuggets::Array::InterpolateMixin

#interpolate

Methods included from Nuggets::Array::CorrelationMixin

#correlation_coefficient, included

Methods included from Nuggets::Array::RegressionMixin

#linear_least_squares, #linear_least_squares_incremental

Methods included from Nuggets::Array::HistogramMixin

#annotated_histogram, #formatted_histogram, #histogram, #probability_mass_function

Methods included from Nuggets::Array::VarianceMixin

#covariance, #variance

Methods included from Nuggets::Array::HashifyMixin

#hashify

Methods included from Nuggets::Array::BlankMixin

#vain?

Methods included from Nuggets::Array::MedianMixin

#median

Methods included from Nuggets::Array::RuniqMixin

#runiq, #runiq!

Methods included from Nuggets::Array::LimitMixin

#cap, #limit

Methods included from Nuggets::Array::FlushMixin

#flush

Methods included from Nuggets::Array::BoostMixin

#boost, #boost_factor, included

Methods included from Nuggets::Array::ModeMixin

included, #mode, #modes

Methods included from Nuggets::Array::MeanMixin

#arithmetic_mean, #generalized_mean, #geometric_mean, #harmonic_mean, #report_mean, #root_mean_square

Instance Method Details

#%(args) ⇒ Object

call-seq:

array % other_array => aString
array % str         => aString

Format–Uses the first string in array for which the corresponding combination of other_array does not contain blank elements as a format specification, and returns the result of applying it to that combination (cf. String#%). Returns an empty string if other_array is empty.

Applies to string argument accordingly: First string in array applied to str; empty string if str is empty.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/nuggets/array/format.rb', line 42

def %(args)
  opts = { :sep => ', ' }
  opts.update(pop) if last.is_a?(::Hash)

  default = lambda { |n| ['%s'] * n * opts[:sep] }

  case args
    when ::String
      return (first || default[1]) % args unless
        args.nil? || args.empty?
    when ::Array
      i = 0
      [*args].comb { |x|
        return (self[i] || default[x.size]) % x unless
          x.empty? || x.any? { |y| y.nil? || y.empty? }

        i += 1
      }
  end

  ''
end

#ascending?(strict = false) ⇒ Boolean Also known as: increasing?

call-seq:

array.ascending? => +true+ or +false+

Check whether array is (strictly) ascending.

Returns:

  • (Boolean)


51
52
53
# File 'lib/nuggets/array/monotone.rb', line 51

def ascending?(strict = false)
  monotone?(strict ? :< : :<=)
end

#comb(*sizes) ⇒ Object

call-seq:

array.comb(n, ...) => new_array
array.comb(n, ...) { |combination| ... } => new_array

Returns an array of arrays of each possible n-combination of array for each given n. If a block is given, each combination is yielded to it. Based on <blade.nagaokaut.ac.jp/~sinara/ruby/math/combinatorics/array-comb.rb>.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/nuggets/array/combination.rb', line 36

def comb(*sizes)
  # If no sizes are given, produce all!
  sizes = (0..size).to_a.reverse if sizes.empty?

  combinations, collect_and_yield = [], lambda { |combination|
    yield combination if block_given?
    combinations << combination
  }

  sizes.each { |n|
    case n
      when 0        # Short-cut (breaks recursion)
        collect_and_yield[[]]
      when 1..size  # Ignore out-of-range values
        self[1..-1].comb(n - 1) { |combination|
          collect_and_yield[combination.unshift(first)]
        }
        self[1..-1].comb(n) { |combination|
          collect_and_yield[combination]
        }
    end
  }

  combinations
end

#descending?(strict = false) ⇒ Boolean Also known as: decreasing?

call-seq:

array.descending? => +true+ or +false+

Check whether array is (strictly) descending.

Returns:

  • (Boolean)


69
70
71
# File 'lib/nuggets/array/monotone.rb', line 69

def descending?(strict = false)
  monotone?(strict ? :> : :>=)
end

#flatten_onceObject

call-seq:

array.flatten_once => new_array

Flatten array by one level only. Pretty straight-forward port of David Alan Black’s flattenx C implementation (though much slower, of course ;-).



34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/nuggets/array/flatten_once.rb', line 34

def flatten_once
  flat = []

  each { |element|
    if element.is_a?(::Array)
      flat += element
    else
      flat << element
    end
  }

  flat
end

#flatten_once!Object

call-seq:

array.flatten_once! => array

Destructive version of #flatten_once.



52
53
54
# File 'lib/nuggets/array/flatten_once.rb', line 52

def flatten_once!
  replace(flatten_once)
end

#in_order(*ordered) ⇒ Object

call-seq:

array.in_order(*ordered) => new_array

Force order, but ignore non-existing and keep remaining.

Examples:

[:created_at, :email, :login, :updated_at].in_order(:login, :email)    #=> [:login, :email, :created_at, :updated_at]
[:created_at, :email, :login, :updated_at].in_order(:email, :address)  #=> [:email, :created_at, :login, :updated_at]


37
38
39
40
# File 'lib/nuggets/array/in_order.rb', line 37

def in_order(*ordered)
  ordered &= self
  ordered + (self - ordered)
end

#in_order!(*ordered) ⇒ Object

call-seq:

array.in_order!(*ordered) => array

Destructive version of #in_order.



46
47
48
# File 'lib/nuggets/array/in_order.rb', line 46

def in_order!(*ordered)
  replace(in_order(*ordered))
end

#monotone?(operator = nil) ⇒ Boolean Also known as: monotonic?

call-seq:

array.monotone?(operator) => +true+ or +false+

Check whether array is monotone according to operator.

Returns:

  • (Boolean)


33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/nuggets/array/monotone.rb', line 33

def monotone?(operator = nil)
  if [nil, true, false].include?(operator)
    ascending?(operator) || descending?(operator)
  else
    inject { |a, b|
      return false unless a.send(operator, b)
      b
    }

    true
  end
end

#only(relax = size == 1) ⇒ Object

call-seq:

array.only => anObject
array.only(+true+) => anObject

Returns the only element of array. Raises an IndexError if array’s size is not 1, unless parameter true is passed.

Idea stolen from Gavin Sinclair’s Ruby Extensions Project.



37
38
39
# File 'lib/nuggets/array/only.rb', line 37

def only(relax = size == 1)
  relax ? first : raise(::IndexError, 'not a single-element array')
end

#randObject

call-seq:

array.rand => anItem

Randomly pick an item from array.



33
34
35
# File 'lib/nuggets/array/rand.rb', line 33

def rand
  at(::Kernel.rand(size))
end

#shuffleObject

call-seq:

array.shuffle => new_array

Shuffles array in random order. Select a different shuffling algorithm: Array.send(:alias_method, :shuffle, :shuffle_kfy).



34
35
36
# File 'lib/nuggets/array/shuffle.rb', line 34

def shuffle
  sort_by { ::Kernel.rand }
end

#shuffle!Object

call-seq:

array.shuffle! => array

Destructive version of #shuffle.



58
59
60
# File 'lib/nuggets/array/shuffle.rb', line 58

def shuffle!
  replace shuffle
end

#shuffle_kfyObject

call-seq:

array.shuffle_kfy => new_array

Non-destructive version of #shuffle_kfy!.



50
51
52
# File 'lib/nuggets/array/shuffle.rb', line 50

def shuffle_kfy
  dup.shuffle_kfy!
end

#shuffle_kfy!Object

call-seq:

array.shuffle_kfy! => array

Shuffles array in random order using the Knuth-Fisher-Yates algorithm.



79
80
81
82
83
84
85
86
# File 'lib/nuggets/array/shuffle.rb', line 79

def shuffle_kfy!
  (length - 1).downto(0) { |i|
    n = rand(i + 1)
    self[n], self[i] = self[i], self[n]
  }

  self
end

#shuffle_knuthObject

call-seq:

array.shuffle_knuth => new_array

Non-destructive version of #shuffle_knuth!.



42
43
44
# File 'lib/nuggets/array/shuffle.rb', line 42

def shuffle_knuth
  dup.shuffle_knuth!
end

#shuffle_knuth!Object

call-seq:

array.shuffle_knuth! => array

Shuffles array in random order using Knuth’s algorithm.



66
67
68
69
70
71
72
73
# File 'lib/nuggets/array/shuffle.rb', line 66

def shuffle_knuth!
  0.upto(length - 2) { |i|
    n = i + rand(length - i)
    self[i], self[n] = self[n], self[i]
  }

  self
end

#sort_by_dotted_decimalObject



55
56
57
# File 'lib/nuggets/dotted_decimal.rb', line 55

def sort_by_dotted_decimal
  sort_by { |i| i.split('.').map { |j| j.to_i } }
end

#strictly_ascending?Boolean Also known as: strictly_increasing?

call-seq:

array.strictly_ascending? => +true+ or +false+

Check whether array is strictly ascending.

Returns:

  • (Boolean)


60
61
62
# File 'lib/nuggets/array/monotone.rb', line 60

def strictly_ascending?
  ascending?(true)
end

#strictly_descending?Boolean Also known as: strictly_decreasing?

call-seq:

array.strictly_descending? => +true+ or +false+

Check whether array is strictly descending.

Returns:

  • (Boolean)


78
79
80
# File 'lib/nuggets/array/monotone.rb', line 78

def strictly_descending?
  descending?(true)
end

#to_hash(value = default = true) ⇒ Object Also known as: to_h

call-seq:

array.to_hash => aHash
array.to_hash(value) => aHash
array.to_hash { |element| ... } => aHash

If neither value nor block is given, converts array, taken as an array of key/value pairs, into a hash, preserving sub-arrays (Thus: hash.to_a.to_h == hash). Otherwise, maps each element of array to value or the result of the block.

Examples:

[[0, 0], [1, [2, 3]]].to_h  #=> { 0 => 0, 1 => [2, 3] }
%w[a b c d].to_h            #=> { "a" => "b", "c" => "d" }
%w[a b c d].to_h(1)         #=> { "a" => 1, "b" => 1, "c" => 1, "d" => 1 }
%w[a b].to_h { |e| e * 2 }  #=> { "a" => "aa", "b" => "bb" }


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/nuggets/array/to_hash.rb', line 46

def to_hash(value = default = true)
  hash = {}

  if block_given?
    raise ::ArgumentError, 'both block and value argument given' unless default

    each { |element| hash[element] = yield element }
  elsif !default
    each { |element| hash[element] = value }
  else
    return ::Hash[*flatten_once]
  end

  hash
end