How to Extract a Sub-Hash from a Hash

How do I extract a sub-hash from a hash?

If you specifically want the method to return the extracted elements but h1 to remain the same:

h1 = {:a => :A, :b => :B, :c => :C, :d => :D}
h2 = h1.select {|key, value| [:b, :d, :e, :f].include?(key) } # => {:b=>:B, :d=>:D}
h1 = Hash[h1.to_a - h2.to_a] # => {:a=>:A, :c=>:C}

And if you want to patch that into the Hash class:

class Hash
def extract_subhash(*extract)
h2 = self.select{|key, value| extract.include?(key) }
self.delete_if {|key, value| extract.include?(key) }
h2
end
end

If you just want to remove the specified elements from the hash, that is much easier using delete_if.

h1 = {:a => :A, :b => :B, :c => :C, :d => :D}
h1.delete_if {|key, value| [:b, :d, :e, :f].include?(key) } # => {:a=>:A, :c=>:C}
h1 # => {:a=>:A, :c=>:C}

How can I get a only part of a hash in Perl?

Hash slices return the values associated with a list of keys. To get a hash slice you change the sigil to @ and provide a list of keys (in this case "a" and "b"):

my @items = @hash{"a", "b"};

Often you can use a quote word operator to produce the list:

my @items = @hash{qw/a b/};

You can also assign to a hash slice, so if you want a new hash that contains a subset of another hash you can say

my %new_hash;
@new_hash{qw/a b/} = @hash{qw/a b/};

Many people will use a map instead of hash slices:

my %new_hash = map { $_ => $hash{$_} } qw/a b/;

Starting with Perl 5.20.0, you can get the keys and the values in one step if you use the % sigil instead of the @ sigil:

my %new_hash = %hash{qw/a b/};

Get the key of a hash by knowing only one item inside the value which is an array in Ruby

This is a way to extract the desired key that is efficient in the sense that it avoids the construction of temporary, intermediate arrays, such as hash.keys, flatten, hash[key], and so on.

target = "known_value"
hash.each_key.find { |k| hash[k].each_value { |a| a.include?(target) } }
#=> "needed key"

This assumes, of course, that we are looking for any key that satisfies the requirement.

Group hashes by keys and sum the values

ar = [{"Vegetable"=>10}, {"Vegetable"=>5}, {"Dry Goods"=>3}, {"Dry Goods"=>2}]
p ar.inject{|memo, el| memo.merge( el ){|k, old_v, new_v| old_v + new_v}}
#=> {"Vegetable"=>15, "Dry Goods"=>5}

Hash.merge with a block runs the block when it finds a duplicate; inject without a initial memo treats the first element of the array as memo, which is fine here.

Ruby - Extract value of a particular key from array of hashes

As you've noticed, it's not very convenient to extract the name of user_id 7. You could modify your data structure a bit :

@profiles = [{:user_id=>5, :full_name=>"Emily Spot"},
{:user_id=>7, :full_name=>"Kevin Walls"}]

@full_names = @profiles.each_with_object({}) do |profile, names|
names[profile[:user_id]] = profile[:full_name]
end

p @full_names
# {5=>"Emily Spot", 7=>"Kevin Walls"}
p @full_names[7]
# "Kevin Walls"
p @full_names[6]
# nil

You didn't lose any information but name look-up is now much faster, easier and more robust.

Find key name in hash with only one key?

A list slice should do it

(keys %h)[0]

keys returns a list, so just extract the first element of that list.

Perl: Is it possible to subset a hash passing a value threshold?

In 5.20+

%subhash = %hash{ grep $hash{$_} >= 3, keys %hash }

(though grep (and map) is still a loop)

How does Python mimic the behavior of Perl multi-level hash chain extraction and concatenation

You have several ways to declare a dictionary in Python. First of all, you can do it straight-forward, in this case:

>>> your_dict = {1: {2: {'C': {'D': 'val'}}}}
>>> print(your_dict)
{1: {2: {'C': {'D': 'val'}}}}
>>> sub_dict = your_dict[1][2]
>>> print(sub_dict)
{'C': {'D': 'val'}}
>>> new_dict = {'A': {'B': sub_list}}
>>> print(new_dict)
{'A': {'B': {'C': {'D': 'val'}}}}

This particular case is not perfectly suitable for using generator expressions, but it's also possible to use them to build a dict. And, of course, you can create a dictionary in a for-loop.

You may be also interested in additional data-types in python, such as: OrderedDict and defaultdict.

If you want to understand how dict objects work, it's a good idea to read this spec.

Some important parts:

object.__len__(self)

Called to implement the built-in function len().
Should return the length of the object, an integer >= 0. Also, an
object that doesn’t define a __nonzero__() method and whose __len__()
method returns zero is considered to be false in a Boolean context.

object.__getitem__(self, key)

Called to implement evaluation of
self[key]. For sequence types, the accepted keys should be integers
and slice objects. Note that the special interpretation of negative
indexes (if the class wishes to emulate a sequence type) is up to the
__getitem__() method. If key is of an inappropriate type, TypeError may be raised; if of a value outside the set of indexes for the
sequence (after any special interpretation of negative values),
IndexError should be raised. For mapping types, if key is missing (not
in the container), KeyError should be raised.

object.__missing__(self, key)

Called by dict.__getitem__() to
implement self[key] for dict subclasses when key is not in the
dictionary.



Related Topics



Leave a reply



Submit