Class: Array

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

Direct Known Subclasses

MonitoredArray

Instance Method Summary collapse

Instance Method Details

#shift_mask_right(mask) ⇒ Object

This shifts any values in the mask all the way to the right, keeping the order of the masked and unmasked items in tact. It’s used for the eviction policies, where I need to update a set of keys in a hash to move down further in the FIFO, without losing their original order.

E.g.: [“a”, 4, “b”, 5, 6, 1, 2, 3].shift_mask_right([‘a’, ‘q’])

> [4, “b”, 5, 6, 1, 2, 3, “a”]

Raises:

  • (StandardError)


44
45
46
47
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
# File 'lib/ext/array.rb', line 44

def shift_mask_right(mask)
  position_of_first_mask = nil
  each_with_index do |e, i|
    if mask.include?(e)
      position_of_first_mask = i
      break
    end
  end
  
  return self unless position_of_first_mask
  
  position_of_first_poser = nil
  each_with_index do |e, i|
    if not mask.include?(e) and i > position_of_first_mask
      position_of_first_poser = i
      break
    end
  end
  
  return self unless position_of_first_poser
  
  position_of_masked_nearest_poser = nil
  (position_of_first_mask...position_of_first_poser).to_a.reverse.each do |i|
    if mask.include?(self[i])
      position_of_masked_nearest_poser = i
      break
    end
  end
  
  raise StandardError, 
    "This should never happen, contact David, the idiot who wrote this algorithm, and tell him Array#shift_mask_right doesn't work." unless 
    position_of_masked_nearest_poser
  
  swap_with_index(position_of_first_poser, position_of_masked_nearest_poser)
  shift_mask_right(mask)
end

#swap(v1, v2) ⇒ Object

This swaps two values in an array:

1,2,3,4].swap(1,3) # => [3,2,1,4

This should work well, unless there are duplicates in the array. Maybe that doesn’t matter for just this, but it matters for the shift_mask_right. I can create an endless loop in that case with that algorithm. So, there’s also swap_with_index.



11
12
13
14
15
16
17
18
# File 'lib/ext/array.rb', line 11

def swap(v1, v2)
  return nil unless self.include?(v1) and self.include?(v2)
  p1 = self.index(v1)
  p2 = self.index(v2)
  self[p1] = v2
  self[p2] = v1
  self
end

#swap_with_index(i1, i2) ⇒ Object Also known as: swap_by_index

This swaps two values by index, so:

%w(a b c d e).swap_with_index(1,5) # => [“e”, “b”, “c”, “d”, “a”]

For shift_mask_right and anything else that depends on all the swapping to be completed, this method must be used rather than swap.



26
27
28
29
30
31
32
# File 'lib/ext/array.rb', line 26

def swap_with_index(i1, i2)
  v1 = self[i1]
  v2 = self[i2]
  self[i1] = v2
  self[i2] = v1
  self
end

#unique_push!(*elements) ⇒ Object Also known as: upush!

Shortcut for a = a | b



82
83
84
85
86
87
# File 'lib/ext/array.rb', line 82

def unique_push!(*elements)
  elements.each do |element|
    self << element unless self.include?(element)
  end
  self
end