Try it yourself with our free Json Formatter tool — runs entirely in your browser, no signup needed.

How to Flatten nested JSON in Ruby

How to Flatten Nested JSON in Ruby

Flattening nested JSON data is a common requirement in many applications, especially when working with third-party APIs or storing data in NoSQL databases. In Ruby, we can use the hashie gem to simplify this process. In this article, we will explore how to flatten nested JSON in Ruby, covering the basics, handling edge cases, common mistakes, and performance tips.

Quick Example

Here is a minimal example that flattens a nested JSON object using the Hashie gem:

require 'hashie'

json_data = {
  "name" => "John",
  "address" => {
    "street" => "123 Main St",
    "city" => "Anytown",
    "state" => "CA",
    "zip" => "12345"
  }
}

flattened_data = Hashie.hsh(json_data).deep_merge

puts flattened_data # => {"name"=>"John", "address.street"=>"123 Main St", "address.city"=>"Anytown", "address.state"=>"CA", "address.zip"=>"12345"}

This example assumes you have the hashie gem installed. You can install it by running gem install hashie in your terminal.

Step-by-Step Breakdown

Let's break down the code:

  1. require 'hashie': We require the hashie gem, which provides the Hashie class.
  2. json_data = { ... }: We define a nested JSON object.
  3. flattened_data = Hashie.hsh(json_data).deep_merge: We create a new Hashie object from the JSON data and call the deep_merge method to flatten the nested structure.

The deep_merge method recursively merges the nested hash into a single-level hash, using the dot notation to concatenate the keys.

Handling Edge Cases

Here are some common edge cases to consider:

Empty/Null Input

If the input JSON data is empty or null, the deep_merge method will raise an error. To handle this, we can add a simple check:

json_data = nil
if json_data.present?
  flattened_data = Hashie.hsh(json_data).deep_merge
else
  flattened_data = {}
end

Invalid Input

If the input JSON data is invalid (e.g., a string instead of a hash), the Hashie constructor will raise an error. To handle this, we can use the Hashie.try_convert method:

json_data = " invalid json "
flattened_data = Hashie.try_convert(json_data)&.deep_merge

Large Input

When dealing with large JSON data, we may encounter performance issues. To improve performance, we can use the Hashie::Mash class, which is optimized for large datasets:

require 'hashie/mash'

json_data = { ... } # large JSON data
flattened_data = Hashie::Mash.new(json_data).deep_merge

Unicode/Special Characters

When dealing with JSON data containing Unicode or special characters, we need to ensure that the Hashie gem can handle them correctly. Fortunately, Hashie uses the json gem under the hood, which supports Unicode and special characters.

Common Mistakes

Here are three common mistakes developers make when flattening nested JSON in Ruby:

Mistake 1: Using merge instead of deep_merge

Using merge instead of deep_merge will only merge the top-level keys, leaving the nested structure intact.

wrong_code = Hashie.hsh(json_data).merge
correct_code = Hashie.hsh(json_data).deep_merge

Mistake 2: Not handling edge cases

Failing to handle edge cases such as empty or invalid input can lead to errors and crashes.

wrong_code = Hashie.hsh(json_data).deep_merge # raises error if json_data is empty
correct_code = if json_data.present?; Hashie.hsh(json_data).deep_merge; end

Mistake 3: Not using Hashie::Mash for large datasets

Using the Hashie class for large datasets can lead to performance issues.

wrong_code = Hashie.hsh(large_json_data).deep_merge # slow
correct_code = Hashie::Mash.new(large_json_data).deep_merge # faster

Performance Tips

Here are three practical performance tips for flattening nested JSON in Ruby:

  1. Use Hashie::Mash for large datasets: As mentioned earlier, Hashie::Mash is optimized for large datasets and can significantly improve performance.
  2. Use deep_merge instead of recursive methods: The deep_merge method is optimized for performance and is generally faster than recursive methods.
  3. Avoid unnecessary allocations: When working with large JSON data, avoid creating unnecessary objects or allocations, as this can lead to performance issues.

FAQ

Q: What is the difference between Hashie and Hashie::Mash?

A: Hashie is the main class, while Hashie::Mash is a subclass optimized for large datasets.

Q: Can I use Hashie with other data formats, such as XML or YAML?

A: No, Hashie is specifically designed for JSON data.

Q: How can I customize the flattening process?

A: You can customize the flattening process by using the Hashie options, such as :namespace_separator or :flatten_arrays.

Q: Is Hashie thread-safe?

A: Yes, Hashie is thread-safe.

Q: Can I use Hashie with Ruby 2.x?

A: Yes, Hashie is compatible with Ruby 2.x, but it's recommended to use the latest version of Ruby for optimal performance.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp