1

I have some JSON that looks like this. I have it stored and read into an object, @items.

[
 {
  {
    "id": "A",
    "description": "a_description"
  }, 
  {
    "id": "B",
    "description": "b_description"
  }
 }, 
 {
  {
    "id": "A",
    "description": "a_description"
  }, 
  {
    "id": "B",
    "description": "b_description"
  }
 }
] 

My goal is to display a table with two columns, one labeled A and the other labeled B, in which each row gives the "a_description" and "b_description". I'm not sure how to go about doing this.

3
  • +1 for your username. And i didnt understand your question. Is the items array populated with this json? Or you have a json and you want to populate the items array? Commented Jul 24, 2012 at 17:55
  • I have the json in a file. From what I understand, when I read in the JSON, I get the items array. Commented Jul 24, 2012 at 18:05
  • It looks like the first sublevel beneath the overall array should also be an array [] not a hash {} right? Commented Jul 24, 2012 at 19:14

2 Answers 2

2

Ah, the ol' array of hashes and hashes of arrays problem.

To get around your "out of order" problem you first have to convert

{
  "id": "A",
  "description": "foo"
},
{
  "id": "B",
  "description": "bar"
}

into {"A" : "foo", "B" : "bar" }.

@new_items = @items.map do |item|
  output = {}
  item.each do |hash|
    output.merge!(hash["id"] => hash["description"])
  end
end

Then @new_items becomes (intentionally presented out of order since hash elements are not ordered)

[
  { 
    "A": "a1_description",
    "B": "b1_description"
  },
  { 
    "B": "b2_description",
    "A": "a2_description"
  }
]

From there, each line is simply a hash, so you can just dereference the value you need based on the column you're in.

@new_items.each do |item|
  puts "#{item['A']} is paired with #{item['B']}"
end

Keys, of course could be retrieved dynamically if you don't want to hard code "A" and "B" using .keys

Sign up to request clarification or add additional context in comments.

2 Comments

I like this solution, but what if items have a third id, "C" ?
Is it a known third id, or will it be dynamic or arbitrary? I kind of hinted at that with the last line, using the .keys method. You can similarly just get an array of all the values (out of order, since it's a hash) using the .values method.
2

Something like this maybe

<tr><th>A</th><th>B</th></tr>
<% @items.each do |item| %>
  <tr><td><%=item[0].description%></td><td><%=item[1].description%></td></tr>
<% end %>

4 Comments

This would work, but it seems like it's possible for the array items to get out of order- I need to check the id, or it's possible that I'll get items in the wrong columns.
Yes- that's the exact problem with this solution- none of the items match up with the column their supposed to, and it's not consistent which column they end up in.
@rapidash, if this is the case. You will need to parse the data the way you want it to be arranged. Just loop through the items and restructure it the way you like before displaying.
Is there any way to do that without individually hardcoding ids for each column? I'd prefer it if I could just generate columns based on what's available.

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.