Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool

Code Kata Exercises for JSON Formatter Proficiency

JSON (JavaScript Object Notation) is ubiquitous in modern web development, serving as a primary format for data exchange. While built-in functions like JSON.stringify({...}, null, 2) handle basic formatting, truly mastering JSON formatting involves understanding its structure deeply and being able to manipulate it programmatically.

Code katas are small, repeatable coding exercises designed to improve skills through practice and repetition. Applying the kata approach to JSON formatting can significantly enhance your ability to parse, transform, and generate JSON strings correctly and efficiently.

Why Practice JSON Formatting?

  • Improved Debugging: Nicely formatted JSON is much easier to read and debug than minified strings.
  • Data Transformation: You might need to reformat JSON for specific APIs, reports, or storage requirements.
  • Deep Understanding: Implementing formatters forces you to understand the nuances of JSON syntax (commas, colons, nesting, string escaping).
  • Custom Requirements: Sometimes standard formatters don't meet specific needs, like sorting keys or filtering properties.

Kata 1: Basic Pretty Print

Goal: Given a minified JSON string, produce a human-readable, indented string.

This is the most fundamental exercise. It involves parsing the JSON into an in-memory structure and then stringifying it with proper indentation. While standard library functions exist, the kata is to understand *how* this is done. A manual implementation might involve tokenizing the string and adding newlines and spaces based on structural elements like {, }, [, ], and ,.

Input Example:

{"name":"Alice","age":30,"isStudent":false,"courses":["Math","Science"]}

Output Example (with 2-space indentation):

{
  "name": "Alice",
  "age": 30,
  "isStudent": false,
  "courses": [
    "Math",
    "Science"
  ]
}

Hint: Think about maintaining an indentation level as you iterate through the string or traverse the parsed structure. Add newlines after `{`, `[`, and after elements followed by `,`. Decrease indent after `}` and `]`.

Kata 2: Minify JSON

Goal: Given a pretty-printed JSON string, remove all non-essential whitespace (spaces, tabs, newlines) while keeping the JSON valid.

This is often simpler than pretty-printing if you parse first. Parse the input string into a data structure, then stringify it without any indentation arguments. Manually, this involves iterating through the string and removing whitespace unless it's inside a quoted string.

Input Example:

{
  "key": "value",
  "nested": {
    "list": [
      1,
      2,
      3
    ]
  }
}

Output Example:

{"key":"value","nested":{"list":[1,2,3]}}

Hint: Be careful not to remove whitespace *within* JSON string values (e.g., "hello world"). A simple approach is to parse and then stringify without formatting. A manual approach needs state to track if you are currently inside a string literal.

Kata 3: Sort Object Keys

Goal: Given a JSON string representing an object (or containing nested objects), produce a pretty-printed JSON string where all object keys are sorted alphabetically.

Standard JSON.stringify does not guarantee key order. This kata requires parsing the JSON, recursively traversing the structure, sorting the keys of any objects encountered, and then stringifying the sorted structure.

Input Example:

{"b": 2, "a": 1, "c": {"z": true, "y": false}}

Output Example (sorted and pretty-printed):

{
  "a": 1,
  "b": 2,
  "c": {
    "y": false,
    "z": true
  }
}

Hint: You'll likely need a recursive function that processes values. If the value is an object, get its keys, sort them, create a new object with keys in sorted order, and recursively process the corresponding values. If it's an array, recursively process each element.

Kata 4: Get Value by Path

Goal: Given a JSON string and a "path" string (similar to lodash or JavaScript accessors, e.g., "user.address.city" or "items[0].name"), return the value at that path. Handle cases where the path doesn't exist.

This kata focuses on navigating the parsed JSON data structure. It requires parsing the input JSON and then implementing logic to traverse the resulting object/array based on the segments of the path string.

Input Example:

{"data":[{"id":1,"name":"Item A"},{"id":2,"name":"Item B"}], "metadata": {"count": 2}}

Path Examples:

  • "data[1].name"
  • "metadata.count"
  • "data[2].id" (path does not exist)

Output Example:

  • For "data[1].name": "Item B"
  • For "metadata.count": 2
  • For "data[2].id": (e.g., undefined or throw an error)

Hint: Parse the path string into segments (e.g., "data[1].name" becomes ["data", "1", "name"], handling the array index carefully). Then, traverse the parsed JSON data structure step by step using these segments. Check if each segment exists before proceeding.

Kata 5: JSON Diff

Goal: Given two JSON strings, identify the differences between them. The output could be a list of changes (additions, deletions, modifications) or a new structure highlighting the differences.

This is a more advanced kata requiring deep structural comparison. Parse both JSON strings into data structures. Then, recursively compare the structures element by element. Objects require comparing keys and their corresponding values. Arrays require comparing elements by index, considering additions, deletions, or changes in order (though JSON doesn't guarantee array order, typical diff assumes ordered arrays).

Input Example:

JSON 1:

{
  "name": "Product A",
  "price": 100,
  "tags": ["electronic", "gadget"],
  "details": {
    "weight": "1kg"
  }
}

JSON 2:

{
  "name": "Product B",
  "price": 120,
  "tags": ["electronic", "new-tag", "gadget"],
  "color": "black",
  "details": {
    "weight": "1.2kg",
    "dimensions": "10x10x10"
  }
}

Output Example (Conceptual Diff):

[
  { "path": "name", "change": "modified", "oldValue": "Product A", "newValue": "Product B" },
  { "path": "price", "change": "modified", "oldValue": 100, "newValue": 120 },
  { "path": "tags[1]", "change": "added", "newValue": "new-tag" },
  { "path": "color", "change": "added", "newValue": "black" },
  { "path": "details.weight", "change": "modified", "oldValue": "1kg", "newValue": "1.2kg" },
  { "path": "details.dimensions", "change": "added", "newValue": "10x10x10" }
]

Hint: This requires careful recursive comparison. For objects, iterate through keys in both objects. If a key exists in one but not the other, it's added/deleted. If it exists in both, recursively compare the values. For arrays, you might compare elements pairwise or use dynamic programming approaches (like the diff algorithm used in text editors) if order changes or elements are added/removed in the middle.

Kata 6: Basic JSON Validation

Goal: Given a string, determine if it is a syntactically valid JSON string.

While simple checks exist, a full validator requires implementing (or simulating) a JSON parser. The kata is to write code that can correctly identify whether a string follows the JSON grammar rules. This involves handling nested structures, correctly quoted strings (with escaped characters), numbers, booleans, and null.

Input Examples:

Valid JSON:

{"valid": true, "array": [1, "two", null]}

Invalid JSON:

{"missing_brace": true
{"extra_comma": [1, 2,]}
{unquoted_key: "value"}

Output Example:

  • For valid JSON: true (or success)
  • For invalid JSON: false (or an error indicating the syntax issue)

Hint: You can attempt to use JSON.parse inside a try-catch block as a simple validation. However, for the kata challenge, try to implement a basic parser that throws an error on invalid syntax. Consider using a state machine or recursive functions based on the JSON grammar.

Benefits of These Katas

Working through these exercises will solidify your understanding of:

  • JSON syntax rules.
  • Parsing techniques (even if simplified).
  • Recursive data structure traversal.
  • String manipulation and whitespace handling.
  • Error handling in data processing.

Start with the basics like Pretty Print and Minify using built-in functions first, then challenge yourself to implement them manually. Gradually move to sorting keys and path finding, which require more complex data structure manipulation. The Diff kata is a significant challenge, perfect for solidifying advanced recursive logic.

Conclusion

Improving proficiency with data formats like JSON is crucial for any developer. These katas provide a structured way to practice essential skills beyond just calling library functions. By tackling these challenges, you'll gain a deeper appreciation for how JSON works and become more capable of handling complex data manipulation tasks in your projects. Happy coding!

Need help with your JSON?

Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool