Class: Array

Inherits:
Object show all
Defined in:
lib/array_pair.rb

Overview

An added method for an array class that return the pairs of classes

Instance Method Summary collapse

Instance Method Details

#averageObject



54
55
56
57
58
59
60
61
# File 'lib/array_pair.rb', line 54

def average
  if Array.new.respond_to?(:sum)
    sum.to_f / length.to_f
  else
    total = 0.0; each{|e| total+=e}
    total / length.to_f
  end
end

#each_lower_triangular_3d_matrixObject

Like each_lower_triangular_matrix, except iterate over 3 items at once, not 2. So for [1,2,3,4] you should get (in succession), 123, 124, 134, 234



212
213
214
215
216
217
218
219
220
221
222
# File 'lib/array_pair.rb', line 212

def each_lower_triangular_3d_matrix
  each_with_index do |e1, i1|
    each_with_index do |e2, i2|
      next unless i2 > i1
      each_with_index do |e3, i3|
        next unless i3 > i2
        yield e1, e2, e3
      end
    end      
  end
end

#each_lower_triangular_4d_matrixObject

Like each_lower_triangular_matrix, except iterate over 4 items at once, not 2.



225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/array_pair.rb', line 225

def each_lower_triangular_4d_matrix
  each_with_index do |e1, i1|
    each_with_index do |e2, i2|
      next unless i2 > i1
      each_with_index do |e3, i3|
        next unless i3 > i2
        each_with_index do |e4, i4|
          next unless i4 > i3
          yield e1, e2, e3, e4
        end
      end
    end      
  end
end

#each_lower_triangular_matrixObject

Similar to pairs(another_array) iterator, in that you iterate over 2 pairs of elements. However, here only the one array (the ‘this’ Enumerable) and the names of these are from the names



200
201
202
203
204
205
206
207
208
# File 'lib/array_pair.rb', line 200

def each_lower_triangular_matrix
  each_with_index do |e1, i|
    if i < length-1
      self[i+1..length-1].each do |e2|
        yield e1, e2
      end
    end
  end
end

#medianObject



182
183
184
185
186
187
188
189
190
# File 'lib/array_pair.rb', line 182

def median
  return nil unless length>0
  a = sort
  if length%2 == 0
    return [a[length/2-1],a[length/2]].average
  else
    return a[length/2]
  end
end

#no_nilsObject



250
251
252
253
254
# File 'lib/array_pair.rb', line 250

def no_nils
  reject do |element|
    element.nil?
  end
end

#normalise_columns(columns_to_normalise = nil) ⇒ Object

Assuming this array is an array of array of numeric/nil values, return the array with each of the columns normalised

This is simple linear scaling to [0,1], so each value v is transformed by transformed = (v-minima)/(maxima_minima) nil values are ignored.

Doesn’t modify the underlying array of arrays in any way, but returns the normalised array



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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
# File 'lib/array_pair.rb', line 94

def normalise_columns(columns_to_normalise=nil)
  column_maxima = []
  column_minima = []
  
  # work out how to normalise the array
  each do |row|
    row.each_with_index do |col, index|
      next unless columns_to_normalise.nil? or columns_to_normalise.include?(index)
      raise Exception, "Unexpected entry class found in array to normalise - expected numeric or nil: #{col}" unless col.nil? or col.kind_of?(Numeric)
      
      # maxima
      if column_maxima[index]
        if !col.nil? and col > column_maxima[index]
          column_maxima[index] = col
        end
      else
        # set it - doesn't matter if it is nil in the end
        column_maxima[index] = col
      end
      
      #minima
      if column_minima[index]
        if !col.nil? and col < column_minima[index]
          column_minima[index] = col
        end
      else
        # set it - doesn't matter if it is nil in the end
        column_minima[index] = col
      end
    end
  end
  
  # now do the actual normalisation
  to_return = []
  each do |row|
    new_row = []
    row.each_with_index do |col, index|
      # if nil, normalise everything
      # if not nil and include, normalise
      # if not nil and not include, don't normalise
      if columns_to_normalise.nil? or columns_to_normalise.include?(index)
        minima = column_minima[index]
        maxima = column_maxima[index]
        
        if col.nil?
          new_row.push nil
        elsif minima == maxima
          new_row.push 0.0
        else
          new_row.push((col.to_f-minima.to_f)/((maxima-minima).to_f))
        end
      else
        new_row.push(col)
      end
    end
    to_return.push new_row
  end
  return to_return
end

#pairs(another_array = nil) ⇒ Object

Return an array of all pairs of elements from this array (each is an array). If another_array is not nil, then do pairwise between this array and that (but not within each)

NOT thread safe.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/array_pair.rb', line 24

def pairs(another_array = nil)
  pairs = []
  
  if another_array #between this array and the next
   (0..length-1).each do |index1|
   (0..another_array.length-1).each do |index2|
        pairs.push [self[index1], another_array[index2]]
      end
    end       
  else # within this array only
   (0..length-1).each do |index1|
      index2 = index1+1
      while index2 < length
        pairs.push [self[index1], self[index2]]
        index2 += 1
      end
    end      
  end
  
  return pairs
end

#pick(*method_symbols) ⇒ Object

Run the method given on each member of the array, then

collect and return the results


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/array_pair.rb', line 65

def pick(*method_symbols)
  if method_symbols.empty?
    return nil
  elsif method_symbols.length > 1
    return collect{|element|
      method_symbols.collect{|meth|
        element.send(meth)
      }
    }
  else
    return collect{|element|
      element.send(method_symbols[0])
    }
  end
  
end

#standard_deviationObject



192
193
194
195
# File 'lib/array_pair.rb', line 192

def standard_deviation
  return nil if empty?
  RSRuby.instance.sd(self)
end

#to_hashObject

make a hash out the array by mapping [element0, element1] to => 0, element1 => 1. Raises an Exception if 2 elements are the same. nil elements are ignored.



157
158
159
160
161
162
163
164
165
# File 'lib/array_pair.rb', line 157

def to_hash
  hash = {}
  each_with_index do |element, index|
    next if element.nil?
    raise Exception, "Multiple elements for #{element}" if hash[element]
    hash[element] = index
  end
  hash
end

#to_sql_in_stringObject

For SQL conditions

‘a’,‘bc’

> “(‘a’,‘bc’)”



169
170
171
172
# File 'lib/array_pair.rb', line 169

def to_sql_in_string
  return '()' if empty?
  return "('#{join("','")}')"
end

#to_sql_in_string_no_quotesObject

For SQL conditions. In [] brackets, single quotes don’t work.

‘a’,‘bc’

> “(a,bc)”



176
177
178
179
# File 'lib/array_pair.rb', line 176

def to_sql_in_string_no_quotes
  return '()' if empty?
  return "(#{join(",")})"
end

#totalObject

Array#sum is not included in Ruby, but is in Rails. Redefining it has problems somehow, so I’m going to use Array#total instead Defining this method seems to make rails fail. Is it defined in Rails somehow as well?

def sum; inject( nil ) { |sum,x| sum ? sum+x : x }; end;


52
# File 'lib/array_pair.rb', line 52

def total; inject( nil ) { |sum,x| sum ? sum+x : x }; end

#uniq_countObject

like uniq -c for unix



241
242
243
244
245
246
247
248
# File 'lib/array_pair.rb', line 241

def uniq_count
  hash = {}
  each do |e|
    hash[e] ||= 0
    hash[e] += 1
  end
  hash
end