Module: Poefy::CoreExtensions::Array::SortByDistance

Included in:
Array
Defined in:
lib/poefy/core_extensions/array.rb,
lib/poefy/core_extensions/array.rb

Overview

– Define module methods. ++

Instance Method Summary collapse

Instance Method Details

#sort_by_distance_from_index(index = nil, reverse: false) ⇒ Object

Take an array index and return a permutation of the items sorted by distance from that index. If ‘index’ is not specified, return an Enumerator of the results for all indices, in order.

The ‘:reverse’ keyword argument switches the equally close neighbours from lowest index first to highest first. It’s an option added mostly for completeness, but it’s there if you need it.



38
39
40
41
42
43
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
80
81
82
# File 'lib/poefy/core_extensions/array.rb', line 38

def sort_by_distance_from_index index = nil, reverse: false

  # Return Enumerator of all possible output arrays.
  if index.nil?
    Enumerator.new(self.count) do |y|
      self.each.with_index do |value, index|
        y << self.sort_by_distance_from_index(index, reverse: reverse)
      end
    end

  # Return Enumerator of results for a single index.
  else
    Enumerator.new(self.count) do |y|
      y << self[index]
      counter = 0
      loop do
        counter += 1

        # Consider negative indices OOB, not from array tail.
        below_index = index - counter
        below_index = nil if below_index < 0
        below = self[below_index] if below_index

        # This is fine, uses nil as default value if OOB.
        above = self[index + counter]

        # Both the elements with index one higher and one lower
        # are equally close neighbours to the subject element.
        # The default is to output the element with the lowest
        # index first. With ':reverse' set to true, the highest
        # index is appended first.
        if reverse
          y << above if above
          y << below if below
        else
          y << below if below
          y << above if above
        end

        # Break if we're at the last element.
        break if !above and !below
      end
    end
  end
end

#sort_by_distance_from_value(value = nil, reverse: false) ⇒ Object

Find all elements that match ‘value’ and return the sort_by_distance results for all, as an Enumerator.



88
89
90
91
92
93
94
95
# File 'lib/poefy/core_extensions/array.rb', line 88

def sort_by_distance_from_value value = nil, reverse: false
  matching = self.each_index.select { |i| self[i] == value }
  Enumerator.new(matching.count) do |y|
    matching.each do |index|
      y << self.sort_by_distance_from_index(index, reverse: reverse)
    end
  end
end