4
\$\begingroup\$

I've written a script that deletes a member of a hash if an array within the has contains all the other elements of another array within the same hash.

It works but it looks a little messy. Is there a better way to do this?

def title_contains_blocks(candidate, titles, index)
  test_group = titles.dup
  test_group.delete_at(index)
  test_group.each do |title|
    return true if true === title[:blocks].all?{|block| candidate[:blocks].include?(block)}
  end

  return false
end

titles = [
  {:blocks => [1,2,3,4,5,6]},
  {:blocks => [1,2,3]},
  {:blocks => [4,5,6]}
]

titles = titles.delete_if.each_with_index {|candidate, index| 
  title_contains_blocks(candidate, titles, index)
}

puts titles.inspect
#=> [{:blocks=>[1, 2, 3]}, {:blocks=>[4, 5, 6]}]
\$\endgroup\$
1
  • \$\begingroup\$ Would it have been equivalent if you removed the [1,2,3] and [4,5,6]? That is, do you simply need to cover all digits and remove redundant entries? \$\endgroup\$ Apr 29, 2012 at 12:36

1 Answer 1

4
\$\begingroup\$

Convert the Hashes to Arrays, then use the difference operations on them.

a = { :a => 1, :b => 2, :c => 2 }
b = { :a => 1 }

p (b.to_a - a.to_a).empty?

You can do other things, like identify if two Hashes overlap in any places, by use the intersection too:

p (a.to_a & b.to_a).any?
\$\endgroup\$
1
  • \$\begingroup\$ in the the first example, if b is a superset of a then it would also result in empty? == true... FYI for everybody trying to compare with this method \$\endgroup\$ Jan 16, 2015 at 7:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.