Reputation: 6906
From a Hash relations
I want to remove some entries and keep the ones I removed in another Hash obj
.
I found Hash.delete_if
and did:
obj = relations.delete_if{|k,v| v[:value] == 1}
However, instead of returning the ones that are removed, it returns the ones that are not removed.
Is there a method that does that?
Upvotes: 1
Views: 784
Reputation: 4496
Try this:
another_hash = {}
relations.delete_if{|k,v| v == 1 ? another_hash[k] = v; true : false}
Upvotes: 2
Reputation: 6644
You could use the partition
method:
{x: 1, y: 0, z: 2, t: 1}.partition {|k, v| v == 1}
# => [[[:x, 1], [:t, 1]], [[:y, 0], [:z, 2]]]
You would then have to turn the results back into hashes, for which you can use the Hash[]
method:
{x: 1, y: 0, z: 2, t: 1}.partition{|k, v| v == 1}.map{|h| Hash[h]}
# => [{:x => 1, :t => 1}, {:y => 0, :z => 2}]
So to do what you were asking:
obj, relations = relations.partition{|k, v| v[:value] == 1}.map{|h| Hash[h]}
Upvotes: 3
Reputation: 230531
I don't know of a built-in method that does this, but building the method yourself is trivial.
def delete_and_return relations, &block
[relations.reject(&block), relations.select(&block)]
end
relations = {
a: {value: 1},
b: {value: 2},
c: {value: 1},
}
kept, deleted = delete_and_return(relations) {|k,v| v[:value] == 1}
kept # => {:b=>{:value=>2}}
deleted # => {:a=>{:value=>1}, :c=>{:value=>1}}
You can even open Hash
class and put the method there.
Upvotes: 0