Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > can it be shorter?

Reply
Thread Tools

can it be shorter?

 
 
Dorren
Guest
Posts: n/a
 
      01-24-2007
doing access control on rails controller,

------ I have this input --------------
hash = {"index" => "list",
["edit", "update"] => "manage_one",
["new", "create", "destroy"] => "manage_all"}

------- I want this output ----------
{"index"=>"list",
"edit"=>"manage_one",
"update"=>"manage_one",
"new"=>"manage_all",
"create"=>"manage_all",
"destroy"=>"manage_all"
}

------ I have this code ------------
hash = Hash[*hash.to_a.collect{|x|
Array === x[0] ? x[0].zip([x[1]]*x[0].size) : x
}.flatten]

----- I want shorter code ------

thanks.

 
Reply With Quote
 
 
 
 
Dorren
Guest
Posts: n/a
 
      01-24-2007
a little clearer than previous one.

hash = Hash[*hash.inject([]){|arr, (k, v)|
arr += Array === k ? k.zip([v]* k.size)
: [k, v]
}.flatten]

 
Reply With Quote
 
 
 
 
Vincent Fourmond
Guest
Posts: n/a
 
      01-24-2007
Dorren wrote:
> doing access control on rails controller,
>
> ------ I have this input --------------
> hash = {"index" => "list",
> ["edit", "update"] => "manage_one",
> ["new", "create", "destroy"] => "manage_all"}
>
> ------- I want this output ----------
> {"index"=>"list",
> "edit"=>"manage_one",
> "update"=>"manage_one",
> "new"=>"manage_all",
> "create"=>"manage_all",
> "destroy"=>"manage_all"
> }
>
> ------ I have this code ------------
> hash = Hash[*hash.to_a.collect{|x|
> Array === x[0] ? x[0].zip([x[1]]*x[0].size) : x
> }.flatten]
>
> ----- I want shorter code ------


What about this:

h = {}
for k,v in hash
[k].flatten.each {|l| h[l] = v}
end
hash = h
> => {"new"=>"manage_all", "edit"=>"manage_one",

"destroy"=>"manage_all", "create"=>"manage_all", "index"=>"list",
"update"=>"manage_one"}

Cheers,

Vincent

--
Vincent Fourmond, PhD student (not for long anymore)
http://vincent.fourmond.neuf.fr/

 
Reply With Quote
 
Vincent Fourmond
Guest
Posts: n/a
 
      01-24-2007
Vincent Fourmond wrote:
> h = {}
> for k,v in hash
> [k].flatten.each {|l| h[l] = v}
> end
> hash = h


Actually, I've got shorter :

h = {}
for k,v in hash
[*k].each {|l| h[l] = v}
end
hash = h

Vince

--
Vincent Fourmond, PhD student (not for long anymore)
http://vincent.fourmond.neuf.fr/

 
Reply With Quote
 
Dorren
Guest
Posts: n/a
 
      01-24-2007
better, thank tou.

On Jan 24, 6:14 pm, Vincent Fourmond <(E-Mail Removed)>
wrote:
> Dorren wrote:
> > doing access control on rails controller,

>
> > ------ I have this input --------------
> > hash = {"index" => "list",
> > ["edit", "update"] => "manage_one",
> > ["new", "create", "destroy"] => "manage_all"}

>
> > ------- I want this output ----------
> > {"index"=>"list",
> > "edit"=>"manage_one",
> > "update"=>"manage_one",
> > "new"=>"manage_all",
> > "create"=>"manage_all",
> > "destroy"=>"manage_all"
> > }

>
> > ------ I have this code ------------
> > hash = Hash[*hash.to_a.collect{|x|
> > Array === x[0] ? x[0].zip([x[1]]*x[0].size) : x
> > }.flatten]

>
> > ----- I want shorter code ------ What about this:

>
> h = {}
> for k,v in hash
> [k].flatten.each {|l| h[l] = v}
> end
> hash = h> => {"new"=>"manage_all", "edit"=>"manage_one","destroy"=>"manage_all", "create"=>"manage_all", "index"=>"list",
> "update"=>"manage_one"}
>
> Cheers,
>
> Vincent
>
> --
> Vincent Fourmond, PhD student (not for long anymore)http://vincent.fourmond.neuf.fr/


 
Reply With Quote
 
William James
Guest
Posts: n/a
 
      01-25-2007


On Jan 24, 5:01 pm, "Dorren" <(E-Mail Removed)> wrote:
> a little clearer than previous one.
>
> hash = Hash[*hash.inject([]){|arr, (k, v)|
> arr += Array === k ? k.zip([v]* k.size)
> : [k, v]
> }.flatten]


Hash[ *hash.map{|k,v| k=[*k]; k.zip([v]*k.size) }.flatten ]

 
Reply With Quote
 
Daniel Martin
Guest
Posts: n/a
 
      01-25-2007
Vincent Fourmond <(E-Mail Removed)> writes:

> Actually, I've got shorter :
>
> h = {}
> for k,v in hash
> [*k].each {|l| h[l] = v}
> end
> hash = h


Well, if we're golfing:

h={};hash.map{|k,v|[*k].map{|t|h[t]=v}};h

--
s=%q( Daniel Martin -- http://www.velocityreviews.com/forums/(E-Mail Removed)
puts "s=%q(#{s})",s.map{|i|i}[1] )
puts "s=%q(#{s})",s.map{|i|i}[1]

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      01-25-2007
On 25.01.2007 03:29, Daniel Martin wrote:
> Vincent Fourmond <(E-Mail Removed)> writes:
>
>> Actually, I've got shorter :
>>
>> h = {}
>> for k,v in hash
>> [*k].each {|l| h[l] = v}
>> end
>> hash = h

>
> Well, if we're golfing:
>
> h={};hash.map{|k,v|[*k].map{|t|h[t]=v}};h


Not really shorter but I though there should be at least one solution
with #inject:

>> hash.inject({}){|h,(k,v)| k.to_a.each {|x| h[x]=v};h}

=> {"new"=>"manage_all", "edit"=>"manage_one", "destroy"=>"manage_all",
"create"=>"manage_all", "index"=>"list", "update"=>"manage_one"}

>> hash.inject({}){|h,(k,v)| k.each {|x| h[x]=v} rescue h[k]=v;h}

=> {"new"=>"manage_all", "edit"=>"manage_one", "destroy"=>"manage_all",
"create"=>"manage_all", "index"=>"list", "update"=>"manage_one"}



robert
 
Reply With Quote
 
Eric Hodel
Guest
Posts: n/a
 
      01-25-2007
--Apple-Mail-2-287622042
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed

On Jan 24, 2007, at 15:20, Vincent Fourmond wrote:
> Vincent Fourmond wrote:
>> h = {}
>> for k,v in hash
>> [k].flatten.each {|l| h[l] = v}
>> end
>> hash = h

>
> Actually, I've got shorter :
>
> h = {}
> for k,v in hash
> [*k].each {|l| h[l] = v}
> end
> hash = h


but fastest (I assume all entries worked correctly):

$ ruby bm.rb
Rehearsal --------------------------------------------------------
original 10.440000 0.010000 10.450000 ( 10.49273
original clean 11.480000 0.040000 11.520000 ( 11.632237)
vince 5.210000 0.010000 5.220000 ( 5.264394)
william 12.760000 0.020000 12.780000 ( 12.814230)
daniel 6.900000 0.010000 6.910000 ( 6.924297)
robert inject 6.560000 0.000000 6.560000 ( 6.588160)
robert inject rescue 6.080000 0.010000 6.090000 ( 6.094140)
---------------------------------------------- total: 59.530000sec

user system total real
original 10.450000 0.010000 10.460000 ( 10.467971)
original clean 11.490000 0.030000 11.520000 ( 11.600672)
vince 5.210000 0.000000 5.210000 ( 5.219863)
william 12.820000 0.010000 12.830000 ( 12.839722)
daniel 6.930000 0.010000 6.940000 ( 6.945329)
robert inject 6.580000 0.010000 6.590000 ( 6.591095)
robert inject rescue 6.080000 0.000000 6.080000 ( 6.117226)


--Apple-Mail-2-287622042
Content-Transfer-Encoding: 7bit
Content-Type: text/x-ruby-script;
x-unix-mode=0644;
name=bm.rb
Content-Disposition: attachment;
filename=bm.rb

require 'benchmark'

N = 500_000

hash = {
"index" => "list",
["edit", "update"] => "manage_one",
["new", "create", "destroy"] => "manage_all"
}

Benchmark.bmbm do |bm|

bm.report 'original' do
N.times do
Hash[*hash.to_a.collect{|x|
Array === x[0] ? x[0].zip([x[1]]*x[0].size) : x
}.flatten]
end
end

bm.report 'original clean' do
N.times do
Hash[*hash.inject([]){|arr, (k, v)|
arr += Array === k ? k.zip([v]* k.size) : [k, v]
}.flatten]
end
end

bm.report 'vince' do
N.times do
h = {}
for k,v in hash
[*k].each {|l| h[l] = v}
end
end
end

bm.report 'william' do
N.times do
Hash[ *hash.map{|k,v| k=[*k]; k.zip([v]*k.size) }.flatten ]
end
end

bm.report 'daniel' do
N.times do
h={};hash.map{|k,v|[*k].map{|t|h[t]=v}}
end
end

bm.report 'robert inject' do
N.times do
hash.inject({}){|h,(k,v)| k.to_a.each {|x| h[x]=v};h}
end
end

bm.report 'robert inject rescue' do
N.times do
hash.inject({}){|h,(k,v)| k.each {|x| h[x]=v} rescue h[k]=v;h}
end
end

end


--Apple-Mail-2-287622042
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed


--
Eric Hodel - (E-Mail Removed) - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!


--Apple-Mail-2-287622042--

 
Reply With Quote
 
Erik Veenstra
Guest
Posts: n/a
 
      01-25-2007
There's a glitch, which is not yet mentioned...

Consider this old hash: {["A", "B"]=>"C", ["B", "A"]=>"D"}

What's the value of new_hash["A"]? Is it "C", or is it "D"?

That depends on the order on which you build the new hash.
Which depends on the order in which you walk through the old
hash. Which isn't deterministic, AFAIK. Maybe it is
determinstic if you know in which order the old hash was built.
But, given _a_ hash, you simply don't know the order in which
you walk through it, so you don't know the order in which the
new hash will be built, so you don't know what the result is
going to be. Cool...

Adding a sort to the algorithm fixes this.

gegroet,
Erik V. - http://www.erikveen.dds.nl/

----------------------------------------------------------------

hash.collect do |k,v|
[[k].flatten, v]
end.sort.inject({}) do |h,(ks,v)|
ks.each do |k|
h[k] = v
end
h
end

----------------------------------------------------------------


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can Groovy be used in an applet and/or can it generate the Java bytecodes that then can be used in an applet? Casey Hawthorne Java 1 03-18-2009 12:56 AM
Word Docs Won't Open, Can't Be E-Mailed, Can't Be Deleted, Can't Be Copied, Etc. Martin Computer Support 16 02-24-2009 07:35 PM
Wireless can get internet but can't see network -- can when wired 02befree Computer Support 0 12-24-2007 09:10 PM
SOLVED - can't open file in windows media player / WMP. But can in VLC - video LAN .. Now can in WMP jameshanley39@yahoo.co.uk Computer Information 2 09-19-2007 02:53 AM
Windows can see mapped drives, but applications can't? =?Utf-8?B?RGFuaWVsIEVpY2hvcm4=?= Wireless Networking 3 11-18-2004 11:03 PM



Advertisments