Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array to Hash snippet #3

Open
birula opened this issue May 1, 2012 · 8 comments
Open

Array to Hash snippet #3

birula opened this issue May 1, 2012 · 8 comments

Comments

@birula
Copy link
Member

birula commented May 1, 2012

I was looking around the code and found this piece of code that turns an array into a Hash. The basic idea is to flatten an array to create a list of key, value and then pass it into a Hash[].

https://github.com/codereading/rack/blob/rack-1.4/lib/rack/request.rb#L57

ary = [ [:foo, "bar"], [:fii, "baz"] ].flatten    #=> [ :foo, "bar", :fii, "baz"]
Hash[ary]                                         #=> {"foo"=> "bar", "fii"=> "baz"}

Hash[*content_type.split(/\s*[;,]\s*/)[1..-1].
  collect { |s| s.split('=', 2) }.
  map { |k,v| [k.downcase, v] }.flatten]

This may be not a big thing but I brought it on because I've used it a couple of times.

@Monomachus
Copy link

what does this other line?

Hash[content_type.split(/\s[;,]\s*/)[1..-1].
collect { |s| s.split('=', 2) }.
map { |k,v| [k.downcase, v] }.flatten]

@samnang
Copy link
Member

samnang commented May 2, 2012

@birula I think you are missing splat operator Hash[ary] in your example, so what it should be is Hash[*ary].

Another interesting collect or map is just an alias of another. Why don't they keep using one consistant instead of mixing in using all together?

@birula
Copy link
Member Author

birula commented May 2, 2012

@samnang You're right i forgot * before the array, just don't now why is it used.

Doesn't it sound like you're trying to map a [key, value] pairs and collect anything else? It looks silly but i use those methods that way.

@birula
Copy link
Member Author

birula commented May 2, 2012

@Monomachus this line convert the header information from a request "text/html; charset=utf-8" into an array [["charset", "utf-8"]] and then to a hash { "charset" => "utf-8" }

If you look closely it excludes the "text/html" from the string in the first step.

@birula
Copy link
Member Author

birula commented May 2, 2012

There's another interesting thing in this code, after the first split it gets the last element with [1..-1] why not just use the .last method ?

content_type.split(/\s*[;,]\s*/)[1..-1]
content_type.split(/\s*[;,]\s*/).last

@tomykaira
Copy link

@birula, try more than one media parameters.

last takes only the last element, whereas [1..-1] takes other than the first element.
Plus, the former returns an object in array, the latter returns an array.

@birula
Copy link
Member Author

birula commented May 2, 2012

@tomykaira you're completely right using last in this case is wrong.

@razum2um
Copy link

razum2um commented May 4, 2012

would it be more efficiently? (or not?)
i.e. would [1..-1] allocate one more array?

content_type.split(/\s*[;,]\s*/).tap(&:shift)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants