Home > Enterprise >  Convert object with array values into array of object
Convert object with array values into array of object

Time:12-30

I do have this kind of params

{"people" => 
  {
    "fname" => ['john', 'megan'],
    "lname" => ['doe', 'fox']
  }
}

Wherein i loop through using this code

result = []
params[:people].each do |key, values|
  
  values.each_with_index do |value, i|
    result[i] = {}
    result[i][key.to_sym] = value
  end

end

The problem on my code is that it always gets the last key and value.

[
 { lname: 'doe' },
 { lname: 'fox' }
]

i want to convert it into

[
  {fname: 'john', lname: 'doe'},
  {fname: 'megan', lname: 'fox'}
]

so that i can loop through of them and save to database.

CodePudding user response:

Your question has been answered but I'd like to mention an alternative calculation that does not employ indices:

keys, values = params["people"].to_a.transpose
  #=> [["fname", "lname"], [["john", "megan"], ["doe", "fox"]]]
[keys].product(values).map { |x,y| x.zip(y).to_h }
  #=> [{"fname"=>"john", "lname"=>"megan"},
  #    {"fname"=>"doe" , "lname"=>"fox"}]

CodePudding user response:

result[i] = {}

The problem is that you're doing this each loop iteration, which resets the value and deletes any existing keys you already put there. Instead, only set the value to {} if it doesn't already exist.

result[i] ||= {}

CodePudding user response:

In your inner loop, you're resetting the i-th element to an empty hash:

result[i] = {}

So you only end up with the data from the last key-value-pair, i.e. lname.

Instead you can use this to only set it to an empty hash if it doesn't already exist:

result[i] ||= {}

So the first loop through, it gets set to {}, but after that, it just gets set to itself.

Alternatively, you can also use

result[i] = {} if !result[i]

which may or may not be more performant. I don't know.

  •  Tags:  
  • ruby
  • Related