0

I have array like

 strings = ["by_product[]=1", "by_product[]=2", "page=1", "per_page=10", "select[]=current", "select[]=requested", "select[]=original"]

which is array of params from request

Then there is code that generates hash from array

arrays = strings.map do |segment|
        k,v = segment.split("=")
        [k, v && CGI.unescape(v)]
Hash[arrays]

CUrrent output -

"by_product[]": "2",
      "page":"1",
      "per_page":"10",
      "select[]":"original"

Expected output -

"by_product[]":"1, 2",
      "page":"1",
      "per_page":"10",
      "select[]":"current, requested, original"

The problem is - after split method there are few by_product[] and the last one just overrides any other params, so in result instead of hash with array as value of these params im getting only last one. And i'm not sure how to fix it. Any ideas? Or at least algorithms

4
  • added more information Commented Jul 10, 2014 at 9:16
  • That's not valid Ruby.. Is it a Hash or Array ? Commented Jul 10, 2014 at 9:17
  • Made it look like a hash, to simplify Commented Jul 10, 2014 at 9:19
  • What is strings value? Commented Jul 10, 2014 at 9:20

4 Answers 4

3

So try this:

hash = {}
arrays = strings.map do |segment|
          k,v = segment.split("=")
          hash[k]||=[]
          hash[k] << v
        end

output is

1.9.3-p547 :025 >   hash
 => {"by_product[]"=>["1", "2"], "page"=>["1"], "per_page"=>["10"], "select[]"=>["current", "requested", "original"]}

or if you want just strings do

arrays = strings.map do |segment|
          k,v = segment.split("=")
          hash[k].nil? ? hash[k] = v : hash[k] << ", " + v
        end
Sign up to request clarification or add additional context in comments.

4 Comments

will try, and give feedback
Assuming the comma's are important in the output I would change both the hash lines on the second one to hash[k].nil? ? hash[k] = v : hash[k] << ", " + v personally
Yes, you are right.@Avdept, consider @Baloo's comment
@pavelS i had to change your code a little bit, so params that have no array, would be like a string and with array would be array-like
2

Don't reinvent the wheel, CGI and Rack can already handle query strings.

Assuming your strings array comes from a single query string:

query = "by_product[]=1&by_product[]=2&page=1&per_page=10&select[]=current&select[]=requested&select[]=original"

you can use CGI::parse: (all values as arrays)

require 'cgi'

CGI.parse(query)
#=> {"by_product[]"=>["1", "2"], "page"=>["1"], "per_page"=>["10"], "select[]"=>["current", "requested", "original"]}

or Rack::Utils.parse_query: (arrays where needed)

require 'rack'

Rack::Utils.parse_nested_query(query)
# => {"by_product[]"=>["1", "2"], "page"=>"1", "per_page"=>"10", "select[]"=>["current", "requested", "original"]}

or Rack::Utils.parse_nested_query: (values without [] suffix)

require 'rack'

Rack::Utils.parse_nested_query(query)
# => {"by_product"=>["1", "2"], "page"=>"1", "per_page"=>"10", "select"=>["current", "requested", "original"]}

And if these are parameters for a Rails controller, you can just use params.

Comments

1

this will also work :

strings.inject({}){ |hash, string| 
  key, value = string.split('='); 
  hash[key] = (hash[key]|| []) << value;
  hash;
}

output : {"by_product[]"=>["1", "2"], "page"=>["1"], "per_page"=>["10"], "select[]"=>["current", "requested", "original"]}

Comments

0

As simple as that

array.map { |record| record*3 if condition }

record*3 is the resultant operation you wanna do to the array while mapping

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.