Class: Array
- Defined in:
- lib/cosmos/core_ext/array.rb,
lib/cosmos/io/json_rpc.rb,
lib/cosmos/tools/limits_monitor/limits_monitor.rb
Overview
Extend Array to search for and delete telemetry items. Telemetry items are Arrays of [target name, packet name, item name].
Direct Known Subclasses
Instance Method Summary collapse
-
#as_json(options = nil) ⇒ Object
:nodoc:.
-
#clone_to_f ⇒ Array
Cloned array after all elements called to_f.
- #delete_item(item) ⇒ Object
-
#histogram(num_buckets = nil, numeric = false, &block) ⇒ Array<Array(first_value, last_value, num_values)>
Array of buckets which are arrays containing the first value that is found in the bucket, the last value found in the bucket, and the total number of values in the bucket.
- #includes_item?(item) ⇒ Boolean
-
#index_gt_eq(value) ⇒ Fixnum
Returns the index of the last element which is greater than or equal to the passed in value.
-
#index_lt_eq(value) ⇒ Fixnum
Returns the index of the first element which is less than or equal to the passed in value.
-
#inspect(max_elements = 10) ⇒ String
String representation of the array.
-
#max_with_index ⇒ Object
Returns the maximum value and its index.
-
#mean ⇒ Object
return [Float] The mean of all the elements in the array.
-
#min_with_index ⇒ Object
Returns the minimum value and its index.
-
#nearest_index(value, ordered_data = true) ⇒ Integer
Returns the array index nearest to the passed in value.
-
#old_inspect ⇒ Object
Redefine inspect to only print for small numbers of items.
-
#range_containing(start_value, end_value) ⇒ Range
Returns the range of array elements which contain both the start value and end value.
-
#range_within(start_value, end_value) ⇒ Range
Returns the range of array elements which within both the start value and end value.
-
#squared ⇒ Object
return [Array] A new array with each value of the original squared.
-
#sum ⇒ Numeric
The sum of all the elements in the array.
Instance Method Details
#as_json(options = nil) ⇒ Object
:nodoc:
74 75 76 |
# File 'lib/cosmos/io/json_rpc.rb', line 74 def as_json( = nil) #:nodoc: map { |v| v.as_json() } end |
#clone_to_f ⇒ Array
Returns Cloned array after all elements called to_f.
32 33 34 35 36 37 38 |
# File 'lib/cosmos/core_ext/array.rb', line 32 def clone_to_f new_array = self.class.new(0) self.each do |value| new_array << value.to_f end new_array end |
#delete_item(item) ⇒ Object
30 31 32 33 34 |
# File 'lib/cosmos/tools/limits_monitor/limits_monitor.rb', line 30 def delete_item(item) found, index = find_item(item) self.delete_at(index) if found return index end |
#histogram(num_buckets = nil, numeric = false, &block) ⇒ Array<Array(first_value, last_value, num_values)>
Returns Array of buckets which are arrays containing the first value that is found in the bucket, the last value found in the bucket, and the total number of values in the bucket.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 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 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
# File 'lib/cosmos/core_ext/array.rb', line 249 def histogram(num_buckets = nil, numeric = false, &block) buckets = {} # Count the occurance of each value self.each do |value| buckets[value] ||= 0 buckets[value] += 1 end # Sort buckets by value, use block for sorting if given if block_given? sorted_buckets = buckets.sort {|x, y| yield(x,y)} else sorted_buckets = buckets.sort end reduced_buckets = [] if num_buckets # Validate num_buckets raise "Invalid num_buckets #{num_buckets}" if num_buckets.to_i <= 0 # Handle histogram types if numeric # Numeric histograms use the same sized range for each bucket first_value = sorted_buckets[0][0] last_value = sorted_buckets[-1][0] delta = last_value - first_value bucket_size = delta.to_f / num_buckets.to_f integers = false integers = true if first_value.kind_of?(Integer) and last_value.kind_of?(Integer) if integers bucket_size = bucket_size.ceil last_value = first_value + bucket_size*num_buckets - 1 delta = last_value - first_value (delta + 1).times do |index| buckets[first_value + index] ||= 0 end if block_given? sorted_buckets = buckets.sort {|val1, val2| yield(val1, val2) } else sorted_buckets = buckets.sort end end bucket_ranges = [] current_value = first_value num_buckets.times do |bucket_index| if bucket_index == (num_buckets - 1) bucket_ranges[bucket_index] = (current_value)..(last_value) else if integers bucket_ranges[bucket_index] = (current_value)..(current_value + bucket_size - 1) else bucket_ranges[bucket_index] = (current_value)..(current_value + bucket_size) end end current_value += bucket_size end # Build the final buckets first_index = 0 sorted_index = 0 num_buckets.times do |bucket_index| break if sorted_index > (sorted_buckets.length - 1) sum = 0 bucket_range = bucket_ranges[bucket_index] while (bucket_range.include?(sorted_buckets[sorted_index][0])) sum += sorted_buckets[sorted_index][1] sorted_index += 1 break if sorted_index > (sorted_buckets.length - 1) end reduced_buckets[bucket_index] = [bucket_range.first, bucket_range.last, sum] end else # Non-numeric histograms use the same number of items per bucket items_per_bucket = sorted_buckets.length / num_buckets.to_i items_per_bucket = 1 if items_per_bucket < 1 bucket_sizes = [items_per_bucket] * num_buckets excess_items = sorted_buckets.length - (items_per_bucket * num_buckets) if excess_items > 0 bucket_sizes.length.times do |bucket_size_index| break if excess_items <= 0 bucket_sizes[bucket_size_index] += 1 excess_items -= 1 end end # Build the final buckets first_index = 0 num_buckets.times do |bucket_index| break if first_index > (sorted_buckets.length - 1) if bucket_index == (num_buckets - 1) last_index = sorted_buckets.length - 1 else last_index = first_index + bucket_sizes[bucket_index] - 1 last_index = sorted_buckets.length - 1 if last_index > (sorted_buckets.length - 1) end sum = 0 sorted_buckets[first_index..last_index].each {|key, value| sum += value} reduced_buckets[bucket_index] = [sorted_buckets[first_index][0], sorted_buckets[last_index][0], sum] first_index = first_index + bucket_sizes[bucket_index] end end else sorted_buckets.each {|key, value| reduced_buckets << [key, key, value]} end reduced_buckets end |
#includes_item?(item) ⇒ Boolean
25 26 27 28 |
# File 'lib/cosmos/tools/limits_monitor/limits_monitor.rb', line 25 def includes_item?(item) found, index = find_item(item) return found end |
#index_gt_eq(value) ⇒ Fixnum
Returns the index of the last element which is greater than or equal to the passed in value.
NOTE: This routine only works on sorted data!
167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/cosmos/core_ext/array.rb', line 167 def index_gt_eq(value) index = nearest_index(value) last_index = self.length - 1 # Keep moving forward if self[index - 1] == value to move past duplicates while (index < last_index and self[index + 1] == value) index += 1 end return index if self[index] >= value index += 1 if (self.length - 1) > index return index end |
#index_lt_eq(value) ⇒ Fixnum
Returns the index of the first element which is less than or equal to the passed in value.
NOTE: This routine only works on sorted data!
146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/cosmos/core_ext/array.rb', line 146 def index_lt_eq(value) index = nearest_index(value) # Keep backing up if self[index - 1] == value to move past duplicates while (index > 0 and self[index - 1] == value) index -= 1 end return index if self[index] <= value index -= 1 if index > 0 return index end |
#inspect(max_elements = 10) ⇒ String
Returns String representation of the array.
23 24 25 26 27 28 29 |
# File 'lib/cosmos/core_ext/array.rb', line 23 def inspect(max_elements = 10) if self.length <= max_elements old_inspect() else '#<' + self.class.to_s + ':' + self.object_id.to_s + '>' end end |
#max_with_index ⇒ Object
Returns the maximum value and its index
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'ext/cosmos/ext/array/array.c', line 20
static VALUE max_with_index (VALUE self)
{
int index = 0;
long array_length = RARRAY_LEN(self);
int maximum_index = 0;
volatile VALUE value = Qnil;
volatile VALUE maximum = Qnil;
volatile VALUE return_value = Qnil;
if (array_length > 0)
{
maximum = rb_ary_entry(self, 0);
maximum_index = 0;
for (index = 1; index < array_length; index++)
{
value = rb_ary_entry(self, index);
if (rb_funcall(value, id_method_greater_than, 1, maximum) == Qtrue)
{
maximum = value;
maximum_index = index;
}
}
}
return_value = rb_ary_new2(2);
rb_ary_push(return_value, maximum);
if (NIL_P(maximum))
{
rb_ary_push(return_value, Qnil);
}
else
{
rb_ary_push(return_value, INT2FIX(maximum_index));
}
return return_value;
}
|
#mean ⇒ Object
return [Float] The mean of all the elements in the array
222 223 224 225 |
# File 'lib/cosmos/core_ext/array.rb', line 222 def mean return 0.0 if self.empty? return self.sum / self.length.to_f end |
#min_with_index ⇒ Object
Returns the minimum value and its index
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'ext/cosmos/ext/array/array.c', line 62
static VALUE min_with_index (VALUE self)
{
int index = 0;
long array_length = RARRAY_LEN(self);
int minimum_index = 0;
volatile VALUE value = Qnil;
volatile VALUE minimum = Qnil;
volatile VALUE return_value = Qnil;
if (array_length > 0)
{
minimum = rb_ary_entry(self, 0);
minimum_index = 0;
for (index = 1; index < array_length; index++)
{
value = rb_ary_entry(self, index);
if (rb_funcall(value, id_method_less_than, 1, minimum) == Qtrue)
{
minimum = value;
minimum_index = index;
}
}
}
return_value = rb_ary_new2(2);
rb_ary_push(return_value, minimum);
if (NIL_P(minimum))
{
rb_ary_push(return_value, Qnil);
}
else
{
rb_ary_push(return_value, INT2FIX(minimum_index));
}
return return_value;
}
|
#nearest_index(value, ordered_data = true) ⇒ Integer
Returns the array index nearest to the passed in value. This only makes sense for numerical arrays containing integers or floats. It has an optimized algorithm if the array is sorted but will fail if passed unsorted data with the sorted option.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 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 |
# File 'lib/cosmos/core_ext/array.rb', line 48 def nearest_index(value, ordered_data = true) raise "Cannot search on empty array" if self.empty? if ordered_data last_index = self.length - 1 first_value = self[0].to_f last_value = self[-1].to_f return 0 if first_value == last_value slope = last_index.to_f / (last_value - first_value) offset = -(slope * first_value) guess_index = ((slope * value.to_f) + offset).to_i # Return immediately for boundary conditions return 0 if guess_index < 0 return last_index if guess_index > last_index # Verify guess index previous_guess_index = nil previous_guess_value = nil # While in the valid range of indexes while (guess_index >= 0 and guess_index <= last_index) # Retrieve the value at our current guess index guess_value = self[guess_index] # We're done if we found the exact value return guess_index if guess_value == value if previous_guess_value # Determine if we did better or worse # Was previous guess better or worse? if (guess_value - value).abs <= (previous_guess_value - value).abs # Previous Guess Worse or the same if guess_value > value # Moving with decreasing indexes if previous_guess_value > value # Still moving in right direction previous_guess_index = guess_index guess_index -= 1 else # We passed the value return guess_index end else # guess_value < value and moving with increasing indexes if previous_guess_value < value # Still moving in right direction previous_guess_index = guess_index guess_index += 1 else # We passed the value return guess_index end end else # Previous Guess Better return previous_guess_index end else # Move to the next point previous_guess_index = guess_index if guess_value > value guess_index -= 1 else #guess_value < value guess_index += 1 end end previous_guess_value = guess_value end # Return our best guess return 0 if guess_index < 0 return last_index else # Brute force search # Calculate the initial delta min_delta = (self[0] - value).abs closest_index = 0 self.each_with_index do |self_value, index| # Calculate the delta between the current value and value we are # searching for delta = (value - self_value).abs # If the newly calculate delta is less than or equal to are previous # minimum delta then we proceed if delta <= min_delta # There is a special case if the delta is equal to the previously # calculated delta. We want to round up in this case so we check if # the value we are searching for is greater than the current value. # If so we skip this value since we don't want to round down. next if (delta == min_delta) and (value > self_value) min_delta = delta closest_index = index end end return closest_index end end |
#old_inspect ⇒ Object
Redefine inspect to only print for small numbers of items. Prevents exceptions taking forever to be raise with large objects. See blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/105145
18 |
# File 'lib/cosmos/core_ext/array.rb', line 18 alias old_inspect inspect |
#range_containing(start_value, end_value) ⇒ Range
Returns the range of array elements which contain both the start value and end value.
NOTE: This routine only works on sorted data!
191 192 193 194 |
# File 'lib/cosmos/core_ext/array.rb', line 191 def range_containing(start_value, end_value) raise "end_value: #{end_value} must be greater than start_value: #{start_value}" if end_value < start_value Range.new(index_lt_eq(start_value), index_gt_eq(end_value)) end |
#range_within(start_value, end_value) ⇒ Range
Returns the range of array elements which within both the start value and end value.
NOTE: This routine only works on sorted data!
206 207 208 209 210 211 212 |
# File 'lib/cosmos/core_ext/array.rb', line 206 def range_within(start_value, end_value) raise "end_value: #{end_value} must be greater than start_value: #{start_value}" if end_value < start_value range = Range.new(index_gt_eq(start_value), index_lt_eq(end_value)) # Sometimes we get a backwards range so check for that and reverse it range = Range.new(range.last, range.first) if range.last < range.first range end |
#squared ⇒ Object
return [Array] A new array with each value of the original squared
228 229 230 |
# File 'lib/cosmos/core_ext/array.rb', line 228 def squared self.map {|value| value * value} end |
#sum ⇒ Numeric
Returns The sum of all the elements in the array.
216 217 218 |
# File 'lib/cosmos/core_ext/array.rb', line 216 def sum self.inject(0, :+) end |