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 bydict.__getitem__()
to
implement self[key] for dict subclasses when key is not in the
dictionary.
Related Topics
What's the Difference Between Gem_Home and Gem_Path
Database Configuration Does Not Specify Adapter
How to Remove Permission Denied @ Rb_Sysopen - Gem Install Error
How to Uninstall Ruby on Rails on MAC Os X
How to Automate Chrome Request Blocking Using Selenium-Webdriver for Ruby
Ruby: How to Convert a String to Boolean
Error: Failed to Build Gem Native Extension When Installing Rails on MAC Mountian Lion Os
Ruby: File Encryption/Decryption with Private/Public Keys
Confusion About Passing Instance Variables to Redirect_To Method. as Seen in Rails Guides
How to Decompress Gzip String in Ruby
Rails 4 Unpermitted Parameters for Array
How to Calculate the Distance Between Two Gps Coordinates Without Using Google Maps API
Gem.Source_Index Is Deprecated, Use Specification. Should I Re-Install Gem or Rails