clean nice way (hash)

S

Shai Rosenfeld

hi,
was wondering what the prettiest way to do the below would be:

i got a hash

{ '1' => 'some', '4' => 'thing', '6' => 'good' }

and i want to turn it into

{ '1' => {'name' => 'some'}, '4' => {'name' => 'thing'}, '6' =>
{'name'=>'good'} }
 
S

SonOfLilit

hash.map{|k, v| {k => {'name' => v}}.to_hash

should work.

Not sure if there's a prettier solution.

Aur
 
S

SonOfLilit

Wait, no.

hash.map{|k, v| k, {'name' => v}}.to_hash

This should work.

Or
h = {}
hash.each{|k, v| h.add(k, {'name' => 'v'})

Aur

hash.map{|k, v| {k => {'name' => v}}.to_hash

should work.

Not sure if there's a prettier solution.

Aur
 
H

hemant

hi,
was wondering what the prettiest way to do the below would be:

i got a hash

{ '1' => 'some', '4' => 'thing', '6' => 'good' }

and i want to turn it into

{ '1' => {'name' => 'some'}, '4' => {'name' => 'thing'}, '6' =>
{'name'=>'good'} }

Dunno, I can think of a couple of ways:

a.each {|key,value| a[key] = {'name' => value}}

or

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }



--
Let them talk of their oriental summer climes of everlasting
conservatories; give me the privilege of making my own summer with my
own coals.

http://blog.gnufied.org
 
S

SonOfLilit

hi,
was wondering what the prettiest way to do the below would be:

i got a hash

{ '1' => 'some', '4' => 'thing', '6' => 'good' }

and i want to turn it into

{ '1' => {'name' => 'some'}, '4' => {'name' => 'thing'}, '6' =>
{'name'=>'good'} }

Dunno, I can think of a couple of ways:

a.each {|key,value| a[key] = {'name' => value}}

Are you allowed to do this?
or

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

Wow, thanks for showing me a new idea.


Aur
 
H

hemant

hi,
was wondering what the prettiest way to do the below would be:

i got a hash

{ '1' => 'some', '4' => 'thing', '6' => 'good' }

and i want to turn it into

{ '1' => {'name' => 'some'}, '4' => {'name' => 'thing'}, '6' =>
{'name'=>'good'} }

Dunno, I can think of a couple of ways:

a.each {|key,value| a[key] = {'name' => value}}

Are you allowed to do this?

Why not? Seem to work here.
or

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

Wow, thanks for showing me a new idea.


Aur


--
Let them talk of their oriental summer climes of everlasting
conservatories; give me the privilege of making my own summer with my
own coals.

http://blog.gnufied.org
 
S

SonOfLilit

a.each {|key,value| a[key] = {'name' => value}}
Why not? Seem to work here.

I was taught not to modify a structure I'm #each ing on...

Does this not apply when you only modify substructures of it?


Aur
 
S

Stefan Rusterholz

SonOfLilit said:
a.each {|key,value| a[key] = {'name' => value}}

Are you allowed to do this?

Why not? Seem to work here.

I was taught not to modify a structure I'm #each ing on...

Does this not apply when you only modify substructures of it?


Aur

I think that only applies for insert/delete. As e.g. with an array it
may happen that elements are left out if you delete them wile iterating,
or that you iterate over a newly create value (which you might not want
to)

Regards
Stefan
 
S

SonOfLilit

SonOfLilit said:
a.each {|key,value| a[key] = {'name' => value}}

Are you allowed to do this?

Why not? Seem to work here.

I was taught not to modify a structure I'm #each ing on...

Does this not apply when you only modify substructures of it?


Aur

I think that only applies for insert/delete. As e.g. with an array it
may happen that elements are left out if you delete them wile iterating,
or that you iterate over a newly create value (which you might not want
to)

Regards
Stefan

You just made me ponder a cool thing:

N = 8
(a = [0, 1]).each_index{|n, i| a << a[i-1] + a if i > 0 and i < N

Of course it probably wouldn't work, but... Cool

Aur
 
J

James Edward Gray II

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II
 
C

Chris Carter

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II

But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}
 
J

James Edward Gray II

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II

But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}

Right, my bad. Thanks.

I just wanted to get away from using inject() like each().

James Edward Gray II
 
R

Robert Klemme

2007/7/16 said:
a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II

But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}

Still it's inefficient because of all the small Hashes that are thrown
away immediately. The solution provided by hemant is better although
not as elegant.

Kind regards

robert
 
J

James Edward Gray II

2007/7/16 said:
On Jul 16, 2007, at 5:58 AM, hemant wrote:

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II

But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}

Still it's inefficient because of all the small Hashes that are thrown
away immediately. The solution provided by hemant is better although
not as elegant.

If that bothers you, change merge() to merge!().

James Edward Gray II
 
R

Robert Dober

Wait, no.

hash.map{|k, v| k, {'name' => v}}.to_hash
Well that is very nice;), but where does #to_hash come from?? (Facets, maybe?)
I suppose it should behave like

def to_hash
Hash[*self]
end


<snip>

Robert
 
F

Florian Aßmann

Robert said:
2007/7/16 said:
On Jul 16, 2007, at 5:58 AM, hemant wrote:

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II

But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}

Still it's inefficient because of all the small Hashes that are thrown
away immediately. The solution provided by hemant is better although
not as elegant.

Kind regards

robert

Hi,

I also tested a theory of mine, Hash#update does this ~20% faster than
Hash#each:

hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] }

Thread ID: 101250
Total: 7.24

%self total self wait child calls name
66.16 7.24 4.79 0.00 2.45 1 Hash#update
33.84 2.45 2.45 0.00 0.00 456976 <Class::Hash>#[]
0.00 7.24 0.00 0.00 7.24 0 Global#[No method]

hash.each { |key, value| hash[key] = Hash['name' => value] }

Thread ID: 101250
Total: 9.28

%self total self wait child calls name
60.78 9.28 5.64 0.00 3.64 1 Hash#each
26.62 2.47 2.47 0.00 0.00 456976 <Class::Hash>#[]
12.61 1.17 1.17 0.00 0.00 456976 Hash#[]=
0.00 9.28 0.00 0.00 9.28 0 Global#[No method]

As I profiled both cases I came across something I don't understand:
When I do the profiling of both cases In the same Ruby process the later
one always is slower as when I profile them seperatly, can somebody
explain this?

Regards
Florian

profile_update.rb:
==================
require 'rubygems'
require 'ruby-prof'

puts 'Hash#update'

hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value|
hash[value] = value
hash
end

result = RubyProf.profile do
hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] }
end
RubyProf::FlatPrinter.new(result).print(STDOUT, 0)


profile_update_first.rb:
========================
require 'rubygems'
require 'ruby-prof'

puts 'Hash#update'

hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value|
hash[value] = value
hash
end

result = RubyProf.profile do
hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] }
end
RubyProf::FlatPrinter.new(result).print(STDOUT, 0)

puts 'Hash#each'

hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value|
hash[value] = value
hash
end

result = RubyProf.profile do
hash.each { |key, value| hash[key] = Hash['name' => value] }
end
RubyProf::FlatPrinter.new(result).print(STDOUT, 0)


profile_each.rb:
================
require 'rubygems'
require 'ruby-prof'

puts 'Hash#each'

hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value|
hash[value] = value
hash
end

result = RubyProf.profile do
hash.each { |key, value| hash[key] = Hash['name' => value] }
end
RubyProf::FlatPrinter.new(result).print(STDOUT, 0)


profile_each_first.rb:
======================
require 'rubygems'
require 'ruby-prof'

puts 'Hash#each'

hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value|
hash[value] = value
hash
end

result = RubyProf.profile do
hash.each { |key, value| hash[key] = Hash['name' => value] }
end
RubyProf::FlatPrinter.new(result).print(STDOUT, 0)

puts 'Hash#update'

hash = ('aaaa'..'zzzz').inject Hash.new do |hash, value|
hash[value] = value
hash
end

result = RubyProf.profile do
hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] }
end
RubyProf::FlatPrinter.new(result).print(STDOUT, 0)
 
R

Robert Klemme

2007/7/16 said:
On Jul 16, 2007, at 5:58 AM, hemant wrote:

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II



But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}

Still it's inefficient because of all the small Hashes that are thrown
away immediately. The solution provided by hemant is better although
not as elegant.

If that bothers you, change merge() to merge!().

.... which doesn't help because it does not avoid all those one pair
hashes. :)

Kind regards

robert
 
R

Robert Klemme

Robert said:
2007/7/16 said:
On Jul 16, 2007, at 5:58 AM, hemant wrote:

a.inject({}) {|mem,(key,value)| mem[key] = {'name' => value}; mem }
I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II


But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}
Still it's inefficient because of all the small Hashes that are thrown
away immediately. The solution provided by hemant is better although
not as elegant.

Kind regards

robert

Hi,

I also tested a theory of mine, Hash#update does this ~20% faster than
Hash#each:

hash.update(hash) { |key, o_val, n_val| Hash['name' => o_val] }

Thread ID: 101250
Total: 7.24

%self total self wait child calls name
66.16 7.24 4.79 0.00 2.45 1 Hash#update
33.84 2.45 2.45 0.00 0.00 456976 <Class::Hash>#[]
0.00 7.24 0.00 0.00 7.24 0 Global#[No method]

hash.each { |key, value| hash[key] = Hash['name' => value] }

Thread ID: 101250
Total: 9.28

%self total self wait child calls name
60.78 9.28 5.64 0.00 3.64 1 Hash#each
26.62 2.47 2.47 0.00 0.00 456976 <Class::Hash>#[]
12.61 1.17 1.17 0.00 0.00 456976 Hash#[]=
0.00 9.28 0.00 0.00 9.28 0 Global#[No method]

As I profiled both cases I came across something I don't understand:
When I do the profiling of both cases In the same Ruby process the later
one always is slower as when I profile them seperatly, can somebody
explain this?

I'd guess it's GC. IMHO for comparing performance Benchmark is a better
tool - especially since you can have a warmup run.

Kind regards

robert
 
J

James Edward Gray II

2007/7/16, Chris Carter <[email protected]>:
On Jul 16, 2007, at 5:58 AM, hemant wrote:

a.inject({}) {|mem,(key,value)| mem[key] = {'name' =>
value}; mem }

I would write that as:

a.inject(Hash.new) { |h, (k, v)| h.merge(k => v) }

James Edward Gray II



But that doesn't yield what he wanted... You could do
a.inject(Hash.new){|h,(k,v)| h.merge(k => { 'name' => value})}

Still it's inefficient because of all the small Hashes that are
thrown
away immediately. The solution provided by hemant is better although
not as elegant.
If that bothers you, change merge() to merge!().

... which doesn't help because it does not avoid all those one pair
hashes. :)

I did eliminate some Hashes, those created for each iteration inject
(), so I feel it's wrong to say it didn't help. You are right about
the parameter Hashes though.

I do feel nitpicking something like this is squarely in the domain of
premature optimization though. It's GC's job to lose sleep over the
objects I create, not mine. I don't need to get involved until it
looks like GC is getting behind. Those are my feelings on the matter.

James Edward Gray II
 
M

Martin DeMello

a.each {|key,value| a[key] = {'name' => value}}

Are you allowed to do this?

Why not? Seem to work here.

I was taught not to modify a structure I'm #each ing on...

Does this not apply when you only modify substructures of it?

It doesn't affect the "spine" of the structure, just the values hanging off it.

martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,745
Messages
2,569,485
Members
44,909
Latest member
DestinyKetoScam

Latest Threads

Top