3

I've been pulling data from an API in JSON, and am currently stumbling over an elmementary problem

The data is on companies, like Google and Facebook, and is in an array or hashes, like so:

[
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>GOOG, "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>FB, "primary_role"=>"company"}}
]

Below are two operations I'd like to try:

  1. For each company, print out the name, ID, and the stock symbol (i.e. "Google - 1 - GOOG" and "Facebook - 2 - FB")
  2. Remove "primary role" key/value from Google and Facebook
  3. Assign a new "industry" key/value for Google and Facebook

Any ideas?

Am a beginner in Ruby, but running into issues with some functions / methods (e.g. undefined method) for arrays and hashes as this looks to be an array OF hashes

Thank you!

3
  • 2
    Hi and welcome to Stack Overflow! To help us help you, it would be great if you could post some example code you've tried, to try to whittle the problem down a bit. Commented May 25, 2018 at 12:40
  • In addition to explaining the transformation steps, could you show how the result should look like? Are there any other entries beside Google and Facebook? If so, how should those be transformed? (maybe just include a non-industry entry in your example and the corresponding result) Commented May 25, 2018 at 12:57
  • If you have further things you'd like to achieve, please create new SO questions for each one. That way they can be answered independently, and has the benefit that you end up with extra SO points :) Commented May 25, 2018 at 13:09

4 Answers 4

15

Ruby provides a couple of tools to help us comprehend arrays, hashes, and nested mixtures of both.

Assuming your data looks like this (I've added quotes around GOOG and FB):

data = [
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "primary_role"=>"company"}}
]

You can iterate over the array using each, e.g.:

data.each do |result|
   puts result["id"]
end

Digging into a hash and printing the result can be done in a couple of ways:

data.each do |result|
  # method 1
  puts result["properties"]["name"]

  # method 2  
  puts result.dig("properties", "name")
end

Method #1 uses the hash[key] syntax, and because the first hash value is another hash, it can be chained to get the result you're after. The drawback of this approach is that if you have a missing properties key on one of your results, you'll get an error.

Method #2 uses dig, which accepts the nested keys as arguments (in order). It'll dig down into the nested hashes and pull out the value, but if any step is missing, it will return nil which can be a bit safer if you're handling data from an external source

Removing elements from a hash

Your second question is a little more involved. You've got two options:

  1. Remove the primary_role keys from the nested hashes, or
  2. Create a new object which contains all the data except the primary_role keys.

I'd generally go for the latter, and recommend reading up on immutability and immutable data structures.

However, to achieve [1] you can do an in-place delete of the key:

data.each do |company| 
  company["properties"].delete("primary_role")
end

Adding elements to a hash

You assign new hash values simply with hash[key] = value, so you can set the industry with something like:

data.each do |company| 
  company["properties"]["industry"] = "Advertising/Privacy Invasion"
end

which would leave you with something like:

[
  {
    "id"=>"1", 
    "properties"=>{
      "name"=>"Google", 
      "stock_symbol"=>"GOOG", 
      "industry"=>"Advertising/Privacy Invasion"
    }
  },
  {
    "id"=>"2", 
    "properties"=>{
      "name"=>"Facebook", 
      "stock_symbol"=>"FB", 
      "industry"=>"Advertising/Privacy Invasion"
    }
  }
]
Sign up to request clarification or add additional context in comments.

Comments

0

To achieve the first operation, you can iterate through the array of companies and access the relevant information for each company. Here's an example in Ruby:

companies = [  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "primary_role"=>"company"}},  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "primary_role"=>"company"}}]

companies.each do |company|
  name = company['properties']['name']
  id = company['id']
  stock_symbol = company['properties']['stock_symbol']
  puts "#{name} - #{id} - #{stock_symbol}"
end

This will print out the name, ID, and stock symbol for each company.

To remove the "primary role" key/value, you can use the delete method on the properties hash. For example:

companies.each do |company|
  company['properties'].delete('primary_role')
end

To add a new "industry" key/value, you can use the []= operator to add a new key/value pair to the properties hash. For example:

companies.each do |company|
  company['properties']['industry'] = 'Technology'
end

This will add a new key/value pair with the key "industry" and the value "Technology" to the properties hash for each company.

Comments

0

this is the shortest way to achieve all those

companies = [
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>GOOG, "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>FB, "primary_role"=>"company"}}
]

companies.each do |company| 
  puts "#{company["properties"]["name"]} - #{company["id"]} - #{company["properties"]["stock_symbol"]} "
  company["properties"].delete("primary_role")
  company[industry] 
end

Comments

0
data = [
  {"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "primary_role"=>"company"}},
  {"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "primary_role"=>"company"}}
]

data.each do |i|
  puts "This is id: #{i.dig("id")}"
  
  # Safely accessing and modifying nested properties
  i.dig("properties")&.delete("primary_role")  # Using dig to safely access "primary_role"
  i.dig("properties")&.store("industry", i.dig("properties", "name"))  # Using dig to access "name" and add "industry"
end

puts data
    Output:

This is id: 1
This is id: 2
{"id"=>"1", "properties"=>{"name"=>"Google", "stock_symbol"=>"GOOG", "industry"=>"Google"}}
{"id"=>"2", "properties"=>{"name"=>"Facebook", "stock_symbol"=>"FB", "industry"=>"Facebook"}}

1 Comment

While this answer looks OK, it is even more helpful when you take some time to explain your code. You can see for yourself that code only answers generally don't get many upvotes, probably because they don't get the attention they deserve. So start your anser by an introduction, and thus help future readers and the appreciation of your answer.

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.