Feature #5531
closeddeep_value for dealing with nested hashes
Added by weexpectedTHIS (Kyle Peyton) almost 14 years ago. Updated almost 9 years ago.
Description
This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size == 1
return self[ks.shift]
else
val = ks.shift
return (self[val].is_a?(Hash) ? self[val].deep_value(*ks) : nil)
end
end
alias dv deep_value
end
deep_value (dv) will simply recurse over a hash given a set of indexes and return the value at the end.
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nil
Updated by ko1 (Koichi Sasada) almost 14 years ago
Actions
#1
[ruby-core:40587]
(2011/11/01 8:52), Kyle Peyton wrote:
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nil
Just idea.
How about to extend Hash#[] for it?
--
// SASADA Koichi at atdot dot net
Updated by rkh (Konstantin Haase) almost 14 years ago
Actions
#2
[ruby-core:40589]
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
On Oct 31, 2011, at 16:52 , Kyle Peyton wrote:
Issue #5531 has been reported by Kyle Peyton.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size
Updated by rkh (Konstantin Haase) almost 14 years ago
Actions
#3
[ruby-core:40590]
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
On Oct 31, 2011, at 16:52 , Kyle Peyton wrote:
Issue #5531 has been reported by Kyle Peyton.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size
Updated by rkh (Konstantin Haase) almost 14 years ago
Actions
#4
[ruby-core:40591]
Never mind, got it.
On Oct 31, 2011, at 17:32 , Haase, Konstantin wrote:
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
On Oct 31, 2011, at 16:52 , Kyle Peyton wrote:
Issue #5531 has been reported by Kyle Peyton.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size
Updated by Eregon (Benoit Daloze) almost 14 years ago
Actions
#5
[ruby-core:40618]
On 1 November 2011 01:26, SASADA Koichi ko1@atdot.net wrote:
(2011/11/01 8:52), Kyle Peyton wrote:
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nilJust idea.
How about to extend Hash#[] for it?--
// SASADA Koichi at atdot dot net
That would be nice.
Updated by alexeymuranov (Alexey Muranov) almost 14 years ago
Actions
#6
[ruby-core:40619]
Konstantin Haase wrote:
Never mind, got it.
On Oct 31, 2011, at 17:32 , Haase, Konstantin wrote:
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
I'll answer anyway if someone else didn't get it :).
{ :foo => 1 }[2][3] raises NoMethodError, and { :foo => 1 }.dv(2,3) or { :foo => 1 }[2,3] should return nil.
Update: also it is possible to keep the list of all arguments in a single variable and call { :foo => 1 }.dv(*args)
Updated by alexeymuranov (Alexey Muranov) almost 14 years ago
Actions
#7
[ruby-core:40624]
I can think of the following questions/objections to the suggested method definition:
- is
{ 1 => 2}.dv(1,1) # => nil
the desired result? - this method examines the (super)class name of an object, rather than the behavior of an object, so does not allow to mix nested hashes and arrays,
- this method calls itself recursively, while a loop would suffice.
The following is not a serious suggestion, but seriously, how about:
class Object
def deep_value(*keys)
obj = self
obj = obj[keys.shift] while !keys.empty? && obj.respond_to?(:[])
return obj
end
end
(For this to work well it will be important to call it #deep_value and not to redefine #[].)
Update. Another suggestion, probably a better one (at least simpler):
class Object
def deep_value(*keys)
obj = self
obj = obj[keys.shift] until keys.empty? || obj.nil?
return obj
end
end
Updated by nobu (Nobuyoshi Nakada) almost 14 years ago
Actions
#8
[ruby-core:40627]
Updated by alexeymuranov (Alexey Muranov) almost 14 years ago
Actions
#9
[ruby-core:40628]
Nobuyoshi Nakada wrote:
=begin
What about:class Hash
def
keys.inject(self) {|container, key| container.fetch(key) {return}}
end
end
=end
Just a small remark about defining this exclusively for Hash: what if some of the values is not a Hash but responds to #fetch? (will not look consistent enough to me).
Updated by trans (Thomas Sawyer) almost 14 years ago
Actions
#10
[ruby-core:40772]
Probably best to use #[] internally too.
class Hash
def [](*keys)
keys.inject(self) {|container, key| value = container[key]; value ? value : return value}
end
end
@Alexey you may have a point. But I suspect it would need to be conditioned off of responding to #to_h or #to_hash instead of using is_a?(Hash)
.
Updated by neleai (Ondrej Bilka) almost 14 years ago
Actions
#11
[ruby-core:40784]
Do you need hash or something like multidimensional hash class that uses [], each iterates on nested...
On Sun, Nov 06, 2011 at 05:48:52PM +0900, Thomas Sawyer wrote:
Issue #5531 has been updated by Thomas Sawyer.
Probably best to use #[] internally too.
class Hash def [](*keys) keys.inject(self) {|container, key| value = container[key]; value ? value : return value} end end
@Alexey you may have a point. But I suspect it would need to be conditioned off of responding to #to_h or #to_hash instead of using
is_a?(Hash)
.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size == 1
return self[ks.shift]
else
val = ks.shift
return (self[val].is_a?(Hash) ? self[val].deep_value(*ks) : nil)
end
endalias dv deep_value
enddeep_value (dv) will simply recurse over a hash given a set of indexes and return the value at the end.
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nil
--
network packets travelling uphill (use a carrier pigeon)
Updated by mame (Yusuke Endoh) over 13 years ago
Actions
#12
- Status changed from Open to Assigned
- Assignee set to matz (Yukihiro Matsumoto)
Updated by weexpectedTHIS (Kyle Peyton) over 13 years ago
Actions
#13
[ruby-core:43882]
What's the status of this issue? Good idea? Bad idea?
Updated by weexpectedTHIS (Kyle Peyton) over 13 years ago
Actions
#14
[ruby-core:45893]
I'd really like to see this in the next version of Ruby, it's a really common pattern.
Updated by weexpectedTHIS (Kyle Peyton) about 13 years ago
Actions
#15
[ruby-core:47796]
I think there is a strong case for this logic built in to ruby.
Updated by mame (Yusuke Endoh) almost 13 years ago
Actions
#16
[ruby-core:49914]
- Priority changed from Normal to 3
- Target version set to 2.6
matz expressed a negative opinion for similar proposal (in Japanese, #5550)
The original in Japanese:
Hashの本質はkey-valueのマッピングなので、valueが再帰的にHashであることを想定した(再帰的なHashでなければ役に立たない)メソッドを追加することには抵抗があります。
English translation:
The essence of Hash is a key-value mapping. I'm negative for adding a method that assumes that the value is a recursive hash, or a method that is useful only for a recursive hash.
--
Yusuke Endoh mame@tsg.ne.jp
Updated by dan.erikson (Dan Erikson) about 9 years ago
Actions
#17
[ruby-core:77528]
I believe this has recently been implemented as Hash#dig
.
Updated by shyouhei (Shyouhei Urabe) almost 9 years ago
Actions
#18
[ruby-core:77827]
- Status changed from Assigned to Closed
Dan Erikson wrote:
I believe this has recently been implemented as
Hash#dig
.
Indeed. Closing peacefully.