Don P
Don P

Reputation: 63667

Transform array of objects in Ruby

I have JSON with one object for each site's traffic for 3 dates.

I want to merge these three objects together on "Date". Example below.

I'm using Ruby. What is the easiest way to do this?

Start JSON:

 [  
   {  
      "Google":[  
         {  
            "Date":"2015-01-01",
            "Value":100
         },
         {  
            "Date":"2015-02-01",
            "Value":200
         },
         {  
            "Date":"2015-03-01",
            "Value":300
         }
      ]
   },
   {  
      "Yahoo":[  
         {  
            "Date":"2015-01-01",
            "Value":1200
         },
         {  
            "Date":"2015-02-01",
            "Value":1300
         },
         {  
            "Date":"2015-03-01",
            "Value":1400
         }
      ]
   },
   {  
      "Bing":[  
         {  
            "Date":"2015-01-01",
            "Value":500
         },
         {  
            "Date":"2015-02-01",
            "Value":600
         },
         {  
            "Date":"2015-03-01",
            "Value":700
         }
      ]
   }
]

End JSON:

[
  {  
    "Date":"2015-01-01",
    "Google":100,
    "Yahoo":1200,
    "Bing":500
  },
  {  
    "Date":"2015-01-02",
    "Google":200,
    "Yahoo":1200,
    "Bing":600
  },
  {  
    "Date":"2015-01-03",
    "Google":300,
    "Yahoo":1400,
    "Bing":700
  }
]

Upvotes: 4

Views: 2654

Answers (2)

undur_gongor
undur_gongor

Reputation: 15954

result = array.inject({}) do | a, e | 
  site, data = e.first
  data.each do | x | 
    a[x[:Date]] ||= {}
    a[x[:Date]][site] = x[:Value]
  end
  a
end

gives you a hash with the dates as keys. This can be transformed to the array by:

result.map { | k, v | v.update(:Date => k) }

Upvotes: 6

djaszczurowski
djaszczurowski

Reputation: 4513

Assuming exactly this structure, what might work is

results = [] 

your_array[0]['Google'].each_with_index do |item, index|
  date = item['Date']

  provider_values = your_array.inject({}) do |memo, current|
    provider = current.keys[0]
    value = current[provider][index]['Value']

    memo[provider] = value
    memo
  end 
  results.push({'Date' => date}.merge(provider_values))
end

I'm currently on Windows so I can't be 100% sure of correctness, however fixing any syntax errors should be easy.

Upvotes: 0

Related Questions