Skip to content

Instantly share code, notes, and snippets.

@baweaver
Created September 16, 2016 17:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baweaver/3273c626cc96a6959843beadb721d0b5 to your computer and use it in GitHub Desktop.
Save baweaver/3273c626cc96a6959843beadb721d0b5 to your computer and use it in GitHub Desktop.
Wherein I do really bad things to hash constructors again.
path_explode_hash = Hash.new { |hash, path|
if path == :*
-> {
prev_paths = [:*]
recurse = -> next_path {
if next_path == :*
prev_paths.push(:*)
recurse
else
[*prev_paths, next_path].reduce(hash) { |target, path|
if path == :*
target.is_a?(Array) ? target.flat_map(&:values) : target.values
else
if target.is_a?(Array)
target.reduce([]) { |a,t| t[path] == {} ? a : a.push(t[path]) }
else
target[path]
end
end
}
end
}
}.call
else
hash[path] = Hash.new(&hash.default_proc)
end
}
path_explode_hash[:a][:b][:c] = 5
path_explode_hash[:a][:b][:d] = 6
path_explode_hash[:a][:g][:d] = 7
path_explode_hash[:a][:g][:c] = 8
path_explode_hash[:a][:m][:d] = 9
path_explode_hash[:a][:m][:x] = 10
p path_explode_hash[:*][:*][:d] # => [6, 7, 9]
p path_explode_hash[:*][:*][:x] # => [10]
p path_explode_hash[:a][:*][:x] # => [10]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment