Created
April 20, 2012 19:52
-
-
Save pmarreck/2431329 to your computer and use it in GitHub Desktop.
attempt to traverse a hash with a key array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module HashUtils | |
# Pass in indexes as an array of keys | |
# def traverse(indexes) | |
# k = indexes.shift | |
# unless k.nil? | |
# v=self[k] | |
# if v.is_a?(Hash) | |
# !indexes.empty? ? v.traverse(indexes) : v | |
# else | |
# indexes.empty? ? v : nil | |
# end | |
# end | |
# end | |
def traverse(indexes) | |
indexes.inject(self){|v, i| v[i] if v.is_a?(Hash)} | |
end | |
# Prune a hash given a hash of any depth (where values can be other hashes) | |
# Takes a block which accepts |k,v| | |
# If the block returns true, that part of the hash is kept | |
# Traversal is breadth-first | |
def prune(&block) | |
inject({}) do |h, (k,v)| | |
if block.call(k, v) | |
h[k] = (v.is_a?(Hash) ? v.prune(&block) : v) | |
end | |
h | |
end | |
end | |
end | |
class Hash | |
include HashUtils | |
end | |
########## inline tests | |
if __FILE__==$0 | |
require 'test/unit' | |
class ReturnValueTest < Test::Unit::TestCase | |
def setup | |
@deep_hash = {a: {b: {c: Test::Unit, d: 5}}} | |
end | |
def test_traverse_valid | |
assert_equal 5, @deep_hash.traverse([:a, :b, :d]) | |
end | |
def test_traverse_value_ends_at_hash | |
assert_equal({c: Test::Unit, d: 5}, @deep_hash.traverse([:a, :b])) | |
end | |
def test_traverse_keypath_invalid_returns_nil | |
assert_equal nil, @deep_hash.traverse([:a, :f, :g]) | |
end | |
# note: the following test was failing with original implementation of traverse | |
def test_traverse_keypath_past_valid_endpoint_returns_nil | |
assert_equal nil, @deep_hash.traverse([:a, :b, :c, :d]) | |
end | |
def test_prune_block_filter | |
assert_equal({a: {b: {d: 5}}}, | |
@deep_hash.prune{|k,v| [Symbol, Hash, Numeric].any?{|c| v.is_a? c }}) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment