简体   繁体   中英

Ruby create hash contents by calling methods

I've got below methods from which I want to build a hash:

methods:

def support_board
  { 'project' => { 'id' => '1234' } }
end

def security_board
  { 'project' => { 'id' => '4352' } }
end

def project_setup
  { 'customfield_12345' => 'None' }
end

expected hash:

{
  'fields' => {
    'project' => { 'id' => '1234' },
    'issuetype' => { 'id' => '4352' },
    'customfield_12345' => 'None'
  }
}

I was trying to something like:

{
  'fields' => {
    support_board,
    security_board,
    project_setup
  }
}

But this is not correct syntax, I'm getting few errors in console - unexpected tSTRING_DEND, expecting end-of-input

You can use Hash#merge! to merge the values in:

{ "fields" => {} }.tap do |return_value|
  return_value['fields'].merge!(support_board, security_board, project_setup)
end
# => {"fields"=>{"project"=>{"id"=>"1234"},
# =>    "issuetype"=>{"id"=>"4352"}, "customfield_12345"=>"None"}}

Or, in older ruby versions, doing it one at a time:

[
  support_board,
  security_board,
  project_setup
].each_with_object({'fields' => {}}) do |method_call, return_value|
  return_value['fields'].merge!(method_call)
end
# => same as above

You're getting a syntax error because you need to provide keys when building a hash.

it's ugly, but a working example that would get you past the syntax issue might look something like this:

{
  'fields' => {
    support_board.keys.first => support_board[support_board.keys.first]
  },
}

But this assumes the hashes returned by the methods only have one key/value pair.

If you are able to change your methods, then consider changing their structure to have a structure that might make it easier to access in a more generic way.

Example:

def support_board
  {
    name: 'project',
    value: { 'id' => '1234' }
  }
end

Then you can do something like this...

{
  'fields' => {
    support_board[:name] => support_board[:value],
    security_board[:name] => security_board[:value],
  },
}

1-liner solution (assuming there's a typo in the method security_board ):

{
  'fields' => [support_board, security_board, project_setup].reduce(&:merge)
}

There's something to digest in this 1-liner though. You may want to do your research on the following things (all links link to the ruby-doc.org):

Well, the documentation of Symbol#to_proc is too simple. According to my experience, the implementation of Symbol#to_proc may look like this:

class Symbol
  def to_proc
    proc {|obj, *args| obj.send(self, *args)}
  end
end

By the way, it also works without the & operator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM