Class: Array

Inherits:
Object show all
Defined in:
lib/ext/array.rb

Instance Method Summary collapse

Instance Method Details

#*(second) ⇒ Object

3 Forms: Multiplied by an Integer, returns a single array with the repeated contents of self Multiplied by a String, returns self.join Multiplied by an Array, returns the set-wise cross-product of the two Arrays



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

def *(second)
  ret = []
  case second
  when Integer
    second.times { |i| ret += dup }
  when String
    return join(second)
  when Array
    each { |x| second.each { |y| ret << [x,y].flatten } }
  else
    raise TypeError.new("can't convert #{second.class} into Integer")
  end
  return ret
end

#**(n) ⇒ Object

Returns the set-wise n-th power of self. (The length of the return value is equal to: self.length ** n) e.g [0,1] ** 0 #=> [] e.g [0,1] ** 1 #=> [[0], [1]] e.g [0,1] ** 2 #=> [[0, 0], [0, 1], [1, 0], [1, 1]] e.g [0,1] ** 3 #=> [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1],

#    [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ext/array.rb', line 54

def **(n)
  type_assert(n, Integer)
  ret = []
  if n > 1
    ret = dup
    (n - 1).times {
      temp = []
      ret.each { |x| each { |y| temp << [x,y].flatten } }
      ret = temp
    }
  elsif n == 1
    ret = map { |item| [item] }
  end
  return ret
end

#chunk(max_length = nil, &block) ⇒ Object

Chunks an array into segments of maximum length

1,2,3,4,5,6,7,8,9,10].chunk(3) #=> [[1,2,3], [4,5,6], [7,8,9], [10]


166
167
168
169
170
171
172
# File 'lib/ext/array.rb', line 166

def chunk(max_length=nil, &block)
  if ::RUBY_VERSION >= "1.9" && block_given?
    super(&block)
  else
    each_slice(max_length).to_a
  end
end

#deep_merge(second) ⇒ Object

Returns a copy of self deep_merged with another array



3
4
5
6
7
# File 'lib/ext/array.rb', line 3

def deep_merge(second)
  target = deep_dup
  target.deep_merge!(second.deep_dup)
  target
end

#deep_merge!(second) ⇒ Object

Deep_merge self with another array



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/ext/array.rb', line 10

def deep_merge!(second)
  return nil unless second
  type_assert(second, Array)
  changed = nil
  second.each_index do |k|
    if self[k].is_a?(Array) and second[k].is_a?(Array)
      changed |= true if self[k].deep_merge!(second[k])
    elsif self[k].is_a?(Hash) and second[k].is_a?(Hash)
      changed |= true if self[k].deep_merge!(second[k])
    elsif exclude?(second[k])
      self << second[k]
      changed |= true
    end
  end
  return nil unless changed
  self
end

#first_quartile(already_sorted = false) ⇒ Object Also known as: lower_quartile

Return the first quartile of self



247
248
249
250
251
# File 'lib/ext/array.rb', line 247

def first_quartile(already_sorted=false)
  return nil if size < 4
  a = already_sorted ? self : sort
  a[0..((size / 2) - 1)].median(true)
end

#frequenciesObject

Calculate the number of occurences for each element of the array



219
220
221
# File 'lib/ext/array.rb', line 219

def frequencies
  inject(Hash.new(0)) { |h,v| h[v] += 1; h }
end

#interquartile_range(already_sorted = false) ⇒ Object

Calculate the interquartile range of self



269
270
271
272
273
# File 'lib/ext/array.rb', line 269

def interquartile_range(already_sorted=false)
  return nil if size < 4
  a = already_sorted ? self : sort
  a.last_quartile - a.first_quartile
end

#last_quartile(already_sorted = false) ⇒ Object Also known as: upper_quartile

Return the last quartile of self



255
256
257
258
259
# File 'lib/ext/array.rb', line 255

def last_quartile(already_sorted=false)
  return nil if size < 4
  a = already_sorted ? self : sort
  a[((size / 2) + 1)..-1].median(true)
end

#map_to_h(&block) ⇒ Object Also known as: map_to_hash

Creates a hash with keys equal to the contents of self and values equal to the mapped array’s values



159
160
161
# File 'lib/ext/array.rb', line 159

def map_to_h(&block)
  [self, map(&block)].transpose.to_h
end

#meanObject Also known as: average

Calculate the arithmetic mean of the array, as long as all objects respond to / operator



210
211
212
213
# File 'lib/ext/array.rb', line 210

def mean
  a = flatten.compact
  (a.size > 0) ? a.sum.to_f / a.size : 0.0
end

#median(already_sorted = false) ⇒ Object Also known as: second_quartile

Return the median of sorted self



238
239
240
241
242
243
# File 'lib/ext/array.rb', line 238

def median(already_sorted=false)
  return nil if empty?
  a = already_sorted ? self : sort
  m_pos = size / 2
  size % 2 == 1 ? a[m_pos] : (a[m_pos-1] + a[m_pos]).to_f / 2
end

#midrange(already_sorted = false) ⇒ Object

Return the midrange of sorted self



283
284
285
286
287
# File 'lib/ext/array.rb', line 283

def midrange(already_sorted=false)
  return nil if empty?
  a = already_sorted ? self : sort
  (a.first + a.last) / 2.0
end

#modesObject

Return a hash of modes with their corresponding occurences



276
277
278
279
280
# File 'lib/ext/array.rb', line 276

def modes
  fre = frequencies
  max = fre.values.max
  fre.select { |k, f| f == max }
end

#not_empty?Boolean

Returns:



174
175
176
# File 'lib/ext/array.rb', line 174

def not_empty?
  !empty?
end

#productObject



188
189
190
# File 'lib/ext/array.rb', line 188

def product
  flatten.compact.inject(:*)
end

#quartiles(already_sorted = false) ⇒ Object

Return an array containing the first, the second and the last quartile of self



263
264
265
266
# File 'lib/ext/array.rb', line 263

def quartiles(already_sorted=false)
  a = already_sorted ? self : sort
  [a.first_quartile(true), a.median(true), a.last_quartile(true)]
end

#ranks(already_sorted = false) ⇒ Object

Return a new array containing the rank of each value Ex: [1, 2, 2, 8, 9] #=> [0.0, 1.5, 1.5, 3.0, 4.0]



199
200
201
202
# File 'lib/ext/array.rb', line 199

def ranks(already_sorted=false)
  a = already_sorted ? self : sort
  map { |i| (a.index(i) + a.rindex(i)) / 2.0 }
end

#sqrtsObject

Calculate square roots of each item



205
206
207
# File 'lib/ext/array.rb', line 205

def sqrts
  map { |i| Math.sqrt(i) }
end

#squaresObject

Calculate squares of each item



193
194
195
# File 'lib/ext/array.rb', line 193

def squares
  map { |i| i ** 2 }
end

#standard_deviation(population = false) ⇒ Object Also known as: std_dev

Return the (sample|population) standard deviation of self If population is set to true, then we consider the dataset as the complete population Else, we consider the dataset as a sample, so we use the sample standard deviation (size - 1)



232
233
234
# File 'lib/ext/array.rb', line 232

def standard_deviation(population=false)
  size > 1 ? Math.sqrt(variance(population)) : 0.0
end

#statistical_range(already_sorted = false) ⇒ Object

Return the statistical range of sorted self



290
291
292
293
294
# File 'lib/ext/array.rb', line 290

def statistical_range(already_sorted=false)
  return nil if empty?
  a = already_sorted ? self : sort
  (a.last - a.first)
end

#statistics(already_sorted = false) ⇒ Object Also known as: stats

Return all statistics from self in a simple hash



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/ext/array.rb', line 297

def statistics(already_sorted=false)
  sorted = sort

  {
    :first => self.first,
    :last => self.last,
    :size => self.size,
    :sum => self.sum,
    :squares => self.squares,
    :sqrts => self.sqrts,
    :min => self.min,
    :max => self.max,
    :mean => self.mean,
    :frequencies => self.frequencies,
    :variance => self.variance,
    :standard_deviation => self.standard_deviation,
    :population_variance => self.variance(true),
    :population_standard_deviation => self.standard_deviation(true),
    :modes => self.modes,

    # Need to be sorted...
    :ranks => sorted.ranks(true),
    :median => sorted.median(true),
    :midrange => sorted.midrange(true),
    :statistical_range => sorted.statistical_range(true),
    :quartiles => sorted.quartiles(true),
    :interquartile_range => sorted.interquartile_range(true)
  }
end

#sumObject

Add each object of the array to each other in order to get the sum, as long as all objects respond to + operator



184
185
186
# File 'lib/ext/array.rb', line 184

def sum
  flatten.compact.inject(:+)
end

#to_h(name_key = "name", value_key = "value") ⇒ Object Also known as: to_hash

Converts certain Arrays to Hashes: [“a”,“b”,“c”].to_h #=> 1=>“b”, 2=>“c” [[1,2], [3,4]].to_h #=> 3=>4 [=> 2, => 4].to_h #=> 3=>4 [=> 1, “value” => 2,

{"name" => 3, "value" => 4}].to_h  #=> {1=>2, 3=>4}

[=> 1, :y => 2,

{:x => 3, :y => 4}].to_h(:x, :y)   #=> {1=>2, 3=>4}

[=> 2, 3 => 4, => 4].to_h #=> 4], 3=>4



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/ext/array.rb', line 111

def to_h(name_key="name", value_key="value")
  #raise "Elements are not unique!" unless self == uniq
  ret = {}
  collisions = Hash.new { |hsh,key| hsh[key] = 0 }
  each_with_index do |elem,index|
    temp = {}
    if elem.is_a?(Hash)
      temp = elem
      if elem[name_key] and elem[value_key] and elem.length == 2
        temp = {elem[name_key] => elem[value_key]}
      elsif elem[name_key.to_s] and elem[value_key.to_s] and elem.length == 2
        temp = {elem[name_key.to_s] => elem[value_key.to_s]}
      elsif elem[name_key.to_sym] and elem[value_key.to_sym] and elem.length == 2
        temp = {elem[name_key.to_sym] => elem[value_key.to_sym]}
      end
    elsif elem.is_a?(Array)
      if elem.length == 2
        temp[elem.first] = elem.last
      elsif elem.length > 2
        temp[elem.first] = elem[1..-1]
      else
        temp[index] = elem.first
      end
    else
      temp[index] = elem
    end
    temp.each do |k,v|
      if ret.has_key?(k)
        if collisions[k] == 0
          if ret[k] != v
            collisions[k] += 1
            ret[k] = [ret[k], v]
          end
        elsif ret[k].exclude?(v)
          collisions[k] += 1
          ret[k] << v
        end
      else
        ret[k] = v
      end
    end
  end
  ret
end

#unanimous?(arg = nil, &block) ⇒ Boolean

1st Form: [1,1,1].unanimous? #=> true [1,1,2].unanimous? #=> false

2nd Form: [1,1,1].unanimous?(1) #=> true [1,1,1].unanimous?(2) #=> false

3rd Form: [1,1,1].unanimous? { |i| i == 2 } #=> true

4th Form: [1,3,5].unanimous?(true) { |i| i % 2 == 1 } #=> true

Returns:



91
92
93
94
95
96
97
98
99
100
# File 'lib/ext/array.rb', line 91

def unanimous?(arg=nil, &block)
  ret = true
  cmp = (arg.nil? ? (block_given? ? block[first] : first) : arg)
  each_with_index do |elem,index|
    next if index == 0 && arg.nil?
    ret &&= (block_given? ? (cmp == block[elem]) : (cmp == elem))
    break unless ret
  end
  ret
end

#uniq_by(&block) ⇒ Object

Returns a new Array rejecting objects based on if the block-mapped values are unique



72
73
74
75
76
# File 'lib/ext/array.rb', line 72

def uniq_by(&block)
  ret = dup
  ret.uniq_by!(&block)
  ret
end

#variance(population = false) ⇒ Object

Return the variance of self



224
225
226
227
# File 'lib/ext/array.rb', line 224

def variance(population=false)
  m = mean.to_f
  map { |v| (v - m) ** 2 }.sum / (size - (population ? 0 : 1))
end