Class: SelfishAssociations::PathMerger
- Inherits:
-
Object
- Object
- SelfishAssociations::PathMerger
- Defined in:
- lib/selfish_associations/utils/path_merger.rb
Instance Attribute Summary collapse
-
#paths ⇒ Object
readonly
Returns the value of attribute paths.
Instance Method Summary collapse
-
#denillify(paths) ⇒ Object
Strip off the nil endpoints in a merged nillified Hash path Array.
-
#hashify_path(path) ⇒ Object
Convert each association index array into a 1-wide, n-deep Hash For algorithmic convenience (see below), applies a nil endpoint to all paths.
-
#initialize(paths) ⇒ PathMerger
constructor
A new instance of PathMerger.
-
#merge ⇒ Object
Take array of arrays in @paths and turn into a nested hash Duplicate keys are collapsed into Array values Endpoint values are guaranteed to be Arrays.
-
#merge_paths(paths, new_path) ⇒ Object
Merge in a new hash path into the current merged hash paths.
Constructor Details
#initialize(paths) ⇒ PathMerger
Returns a new instance of PathMerger.
5 6 7 |
# File 'lib/selfish_associations/utils/path_merger.rb', line 5 def initialize(paths) @paths = paths.select(&:present?) end |
Instance Attribute Details
#paths ⇒ Object (readonly)
Returns the value of attribute paths.
3 4 5 |
# File 'lib/selfish_associations/utils/path_merger.rb', line 3 def paths @paths end |
Instance Method Details
#denillify(paths) ⇒ Object
Strip off the nil endpoints in a merged nillified Hash path Array. 1-deep paths get un-Hashed. I.e., => nil becomes just key. >1-deep Hashes are guaranteed to have Hash values. So, from above,
{:a => {:b => {:c => nil}, {:x => nil}}}
now becomes
{:a => [:x, {:b => :c}]}
57 58 59 60 61 62 63 |
# File 'lib/selfish_associations/utils/path_merger.rb', line 57 def denillify(paths) singles, hashes = paths.keys.partition{|k| paths[k].nil?} hashes.each{|k| paths[k] = denillify(paths[k])} return_array = singles return_array << paths.slice(*hashes) if hashes.present? return return_array.length == 1 ? return_array.first : return_array end |
#hashify_path(path) ⇒ Object
Convert each association index array into a 1-wide, n-deep Hash For algorithmic convenience (see below), applies a nil endpoint to all paths. So
[:a, :b, :c]
becomes
{:a => {:b => {:c => nil}}}
24 25 26 |
# File 'lib/selfish_associations/utils/path_merger.rb', line 24 def hashify_path(path) path.reverse.reduce(nil){|path_partial, node| {node => path_partial}} end |
#merge ⇒ Object
Take array of arrays in @paths and turn into a nested hash Duplicate keys are collapsed into Array values Endpoint values are guaranteed to be Arrays
12 13 14 15 |
# File 'lib/selfish_associations/utils/path_merger.rb', line 12 def merge merged_paths = @paths.reduce({}){|merged, path| merge_paths(merged, hashify_path(path))} return denillify(merged_paths) end |
#merge_paths(paths, new_path) ⇒ Object
Merge in a new hash path into the current merged hash paths. Dup keys are combined as a merged Hash themselves: we need recursion! Non-nil values are guaranteed to be Hashes because we’ve introduced the nil endpoint Therefore we can simply merge all non-nil values recursivelye So
[[:a, :b, :c], [:a, :b], [:a, :x]
which hashifies into (remembering that we add nil endpoints)
[{:a => {:b => {:c => nil}}}, {:a => {:b => :nil}}, {:a => {:x => nil}}]
now becomes
{:a => {:b => {:c => nil}, {:x => nil}}}
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/selfish_associations/utils/path_merger.rb', line 38 def merge_paths(paths, new_path) paths.merge!(new_path) do |parent_node, oldval, newval| if oldval.nil? || newval.nil? # If either old or new path ended at parent_node, use the other oldval || newval else # Else both paths continue from this node: recurse down the path! merge_paths(oldval, newval) end end end |