[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

can it be shorter?

nicknameoptional

1/24/2007 10:42:00 PM

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.

9 Answers

nicknameoptional

1/24/2007 11:02:00 PM

0

a little clearer than previous one.

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

Vincent Fourmond

1/24/2007 11:15:00 PM

0

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.fourmon...

Vincent Fourmond

1/24/2007 11:20:00 PM

0

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.fourmon...

nicknameoptional

1/24/2007 11:27:00 PM

0

better, thank tou.

On Jan 24, 6:14 pm, Vincent Fourmond <vincent.fourm...@9online.fr>
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.fourmon...

William James

1/25/2007 1:51:00 AM

0



On Jan 24, 5:01 pm, "Dorren" <dorrenc...@gmail.com> 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 ]

Daniel Martin

1/25/2007 2:30:00 AM

0

Vincent Fourmond <vincent.fourmond@9online.fr> 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 -- martin@snowplow.org
puts "s=%q(#{s})",s.map{|i|i}[1] )
puts "s=%q(#{s})",s.map{|i|i}[1]

Robert Klemme

1/25/2007 10:02:00 AM

0

On 25.01.2007 03:29, Daniel Martin wrote:
> Vincent Fourmond <vincent.fourmond@9online.fr> 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

Eric Hodel

1/25/2007 10:28:00 AM

0


--
Eric Hodel - drbrain@segment7.net - http://blog.se...

I LIT YOUR GEM ON FIRE!

Erik Veenstra

1/25/2007 11:49:00 AM

0

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.erikve...

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

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

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