Convert JSON Values to a Compact String

Quick Overview

Serialize JSON values in JavaScript without JSON.stringify. Preserve array and Object.keys order, compact formatting and primitive roots while supporting deeply nested data.

Convert JSON Values to a Compact String

Company: Apple

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Other

### Problem Implement `jsonStringify(object)` in JavaScript. Return a string containing the compact JSON representation of the supplied value without calling the built-in `JSON.stringify` method. The input is a valid JSON value: a string, number, boolean, `null`, array, or object. Arrays and objects may contain other JSON values. Preserve array order. For every object, emit keys in exactly the order returned by `Object.keys()` for that object. Do not sort them yourself or insert formatting spaces. ### Input Domain and Output Details - All strings, including object keys, contain only alphanumeric characters. Empty strings are permitted. This restriction means the exercise does not require escaping quotation marks, backslashes or control characters inside strings. - Inputs are JSON data trees. Cycles, sparse arrays, `undefined`, functions, symbols, `BigInt`, nonfinite numbers and custom serialization hooks are outside this contract. Getters and proxies with behavior are not part of the data-tree model. - Primitive roots are valid: for example, a boolean input still returns a string, not a boolean. - For this written exercise's exact-output comparisons, use ordinary JavaScript finite-number string conversion, including `-0` becoming `"0"`. Decimal and exponent notation follow that conversion. This spells out a comparison policy; the source asks for valid compact JSON without separately defining equivalent numeric spellings. ### Examples **Example 1:** Input: ```javascript { b: 2, a: 1 } ``` Returned string contents: ```json {"b":2,"a":1} ``` For these keys, `Object.keys()` returns `b` before `a`. **Example 2:** Input: ```javascript { item: { code: "A7", flags: [true, null, {}] } } ``` Returned string contents: ```json {"item":{"code":"A7","flags":[true,null,{}]}} ``` An empty object remains `{}`, and nested values follow the same rules as the root. The code blocks show the contents of the returned string, not its JavaScript source-literal wrapper. ### Constraints and Clarifications - The length of the built-in JSON representation would be `1..100,000` under JavaScript string-length semantics. That bound does not permit calling `JSON.stringify` in your solution. - Maximum nesting level is `1000`. - Object member names are strings. Numeric-looking keys must still follow `Object.keys()` order, which can differ from their insertion order. - Return a string for every allowed root, including `null`, numbers and booleans. - Do not add whitespace for readability. ```hint Preserve order at every level Decide how each allowed value kind contributes its delimiters and contents. Nested values must obey the same ordering rules as the root. ``` ### What a Strong Answer Covers - Distinguish `null`, arrays and ordinary objects despite their related `typeof` results. - Emit quotes, commas, colons and container delimiters in the correct places, including empty containers. - Preserve array order and `Object.keys()` order at every nesting level. - Handle primitive roots and the full nesting limit without the forbidden serializer. - Relate time and storage costs to the produced text and pending traversal work. ### Follow-up Questions - Why can lexically sorting keys disagree with `Object.keys()`? - How can you support depth 1000 without depending on the engine's recursive call-stack limit? - What extra work would become necessary if strings could contain quotes, backslashes or control characters?

Overview: Serialize JSON values in JavaScript without JSON.stringify. Preserve array and Object.keys order, compact formatting and primitive roots while supporting deeply nested data.

Apple logo
Apple
mediumSoftware EngineerOtherCoding & Algorithms
0
0

Problem

Implement jsonStringify(object) in JavaScript. Return a string containing the compact JSON representation of the supplied value without calling the built-in JSON.stringify method.

The input is a valid JSON value: a string, number, boolean, null, array, or object. Arrays and objects may contain other JSON values. Preserve array order. For every object, emit keys in exactly the order returned by Object.keys() for that object. Do not sort them yourself or insert formatting spaces.

Input Domain and Output Details

  • All strings, including object keys, contain only alphanumeric characters. Empty strings are permitted. This restriction means the exercise does not require escaping quotation marks, backslashes or control characters inside strings.
  • Inputs are JSON data trees. Cycles, sparse arrays, undefined , functions, symbols, BigInt , nonfinite numbers and custom serialization hooks are outside this contract. Getters and proxies with behavior are not part of the data-tree model.
  • Primitive roots are valid: for example, a boolean input still returns a string, not a boolean.
  • For this written exercise's exact-output comparisons, use ordinary JavaScript finite-number string conversion, including -0 becoming "0" . Decimal and exponent notation follow that conversion. This spells out a comparison policy; the source asks for valid compact JSON without separately defining equivalent numeric spellings.

Examples

Example 1:

Input:

{ b: 2, a: 1 }

Returned string contents:

{"b":2,"a":1}

For these keys, Object.keys() returns b before a.

Example 2:

Input:

{ item: { code: "A7", flags: [true, null, {}] } }

Returned string contents:

{"item":{"code":"A7","flags":[true,null,{}]}}

An empty object remains {}, and nested values follow the same rules as the root. The code blocks show the contents of the returned string, not its JavaScript source-literal wrapper.

Constraints and Clarifications

  • The length of the built-in JSON representation would be 1..100,000 under JavaScript string-length semantics. That bound does not permit calling JSON.stringify in your solution.
  • Maximum nesting level is 1000 .
  • Object member names are strings. Numeric-looking keys must still follow Object.keys() order, which can differ from their insertion order.
  • Return a string for every allowed root, including null , numbers and booleans.
  • Do not add whitespace for readability.

What a Strong Answer Covers Guidance

  • Distinguish null , arrays and ordinary objects despite their related typeof results.
  • Emit quotes, commas, colons and container delimiters in the correct places, including empty containers.
  • Preserve array order and Object.keys() order at every nesting level.
  • Handle primitive roots and the full nesting limit without the forbidden serializer.
  • Relate time and storage costs to the produced text and pending traversal work.

Follow-up Questions Guidance

  • Why can lexically sorting keys disagree with Object.keys() ?
  • How can you support depth 1000 without depending on the engine's recursive call-stack limit?
  • What extra work would become necessary if strings could contain quotes, backslashes or control characters?