Skip to content

Commit

Permalink
EPB-11376 refactor deep_find and deep_find_parent logic methods to re…
Browse files Browse the repository at this point in the history
…turn false if a key has that value
  • Loading branch information
p-sqr committed Sep 30, 2024
1 parent d293d4b commit ac7eee5
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
14 changes: 9 additions & 5 deletions lib/hash_miner/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,37 +245,41 @@ def deep_remove_logic_parent(hash:, key:, parent:)
end

def deep_find_logic(hash:, key:)
hash.filter_map do |k, v|
results = hash.map do |k, v|
if k.eql? key
v
elsif v.is_a?(Hash)
deep_find_logic(hash: v, key: key)
elsif v.is_a?(Array)
[v.filter_map do |item|
[v.map do |item|
deep_find_logic(hash: item, key: key) if item.is_a?(Hash) && item.deep_contains?(key: key)
end]
end
end.flatten

results.all?(nil) ? results.uniq : results.compact
end

def deep_find_parent_logic(hash:, key:, parent:)
hash.filter_map do |k, v|
results = hash.map do |k, v|
if (parent.is_a?(Array) && parent.include?(k)) || parent.eql?(k)
case v
when Hash
deep_find_logic(key: key, hash: v)
when Array
[v.filter_map do |item|
[v.map do |item|
deep_find_logic(key: key, hash: item) if item.is_a?(Hash) && item.deep_contains?(key: key)
end]
end
elsif v.is_a?(Hash) && v.deep_contains?(key: key)
deep_find_parent_logic(hash: v, key: key, parent: parent)
elsif v.is_a?(Array)
[v.filter_map do |item|
[v.map do |item|
deep_find_parent_logic(hash: item, key: key, parent: parent) if item.is_a?(Hash) && item.deep_contains?(key: key)
end]
end
end.flatten

results.all?(nil) ? results.uniq : results.compact
end
end
31 changes: 22 additions & 9 deletions spec/hash_miner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

RSpec.describe HashMiner do
before(:example) do
@nasty_hash = { my: { super: { duper: { deeply: 'nested hash',
is: [{ duper: 'gross', random: nil }, 'a', 1, nil] } },
hey: { duper: :a, blah: '', foo: [nil] },
deeply: [{ nested: 'hash' }] } }
@nasty_hash = { my:
{ super:
{ duper:
{ deeply: 'nested hash', is: [{ duper: 'gross', random: nil }, 'a', 1, nil] } },
hey: { duper: :a, blah: '', foo: [nil] },
test: nil,
not_true: { my_false_key: false },
deeply: [{ nested: 'hash' }] },
more_deeplyer: { test: nil } }
end

it 'has a version number' do
Expand All @@ -15,8 +20,9 @@
context ' deep_contains?' do
it 'returns true when key found' do
expect(@nasty_hash.deep_contains?(key: :foo)).to be true
expect(@nasty_hash.deep_contains?(key: :my_false_key)).to be true
end
it 'returns false when key found' do
it 'returns false when key not found' do
expect(@nasty_hash.deep_contains?(key: [:foo])).to be false
expect(@nasty_hash.deep_contains?(key: 'foo')).to be false
expect(@nasty_hash.deep_contains?(key: nil)).to be false
Expand All @@ -32,9 +38,10 @@
it 'returns the count when key found' do
expect(@nasty_hash.deep_count(key: :foo)).to eq 1
expect(@nasty_hash.deep_count(key: :duper)).to eq 3
expect(@nasty_hash.deep_count(key: :my_false_key)).to eq 1
end

it 'returns 0 when key found' do
it 'returns 0 when key not found' do
expect(@nasty_hash.deep_count(key: [:foo])).to eq 0
expect(@nasty_hash.deep_count(key: 'foo')).to eq 0
expect(@nasty_hash.deep_count(key: nil)).to eq 0
Expand All @@ -55,12 +62,16 @@
])
expect(@nasty_hash.deep_find(key: :deeply)).to eq(['nested hash', { nested: 'hash' }])
expect(@nasty_hash.deep_find(key: :nested)).to eq(['hash'])
expect(@nasty_hash.deep_find(key: :not_true)).to eq([{ my_false_key: false }])
expect(@nasty_hash.deep_find(key: :my_false_key)).to eq([false])
end

it 'returns nil when key not found' do
expect(@nasty_hash.deep_find(key: [:foo])).to be nil
expect(@nasty_hash.deep_find(key: 'foo')).to be nil
expect(@nasty_hash.deep_find(key: nil)).to be nil
expect(@nasty_hash.deep_find(key: 'does_not_exist')).to be nil

end

it 'returns nil when not a Hash object' do
Expand All @@ -71,12 +82,13 @@
it 'can be scoped with a parent key' do
expect(@nasty_hash.deep_find(key: :duper, parent: :hey)).to eq([:a])
expect(@nasty_hash.deep_find(key: :duper, parent: [:hey])).to eq([:a])
expect(@nasty_hash.deep_find(key: :my_false_key, parent: :not_true)).to eq([false])
expect(@nasty_hash.deep_find(key: :duper,
parent: %i[hey
super])).to eq([
{ deeply: 'nested hash',
is: [{ duper: 'gross', random: nil }, 'a', 1, nil] }, :a
])
{ deeply: 'nested hash',
is: [{ duper: 'gross', random: nil }, 'a', 1, nil] }, :a
])
end

it 'will only find keys if within a parent if given' do
Expand All @@ -100,6 +112,7 @@
is: [{ duper: 'gross' }, 'a', 1,
nil] } },
hey: { duper: :a, foo: [nil] },
not_true: { my_false_key: false },
deeply: [{ nested: 'hash' }] } })
end
end
Expand Down

0 comments on commit ac7eee5

Please sign in to comment.