Mystery Object

Render an arbitrarily nested JavaScript Object.


Environment

Use the environment you are most comfortable with. I recommend using create-react-app to create a local version of the project so that you can inspect the DOM easily from your browser when debugging. Alternatively, you can work from a blank React template in CodeSandbox. Starter code is provided after the problem specification.

Specification

Write a functional component that accepts an arbitrarily nested object as a prop. Each key/property of the object is a word and its associated value is either (1) an object of the same format or (2) a definition string. An example of one such object is below.

{
    taxi: "a car licensed to transport passengers in return for payment of a fare",
    food: {
      sushi:
        "a traditional Japanese dish of prepared rice accompanied by seafood and vegetables",
      apple: {
        Honeycrisp:
          "an apple cultivar developed at the MAES Horticultural Research Center",
        Fuji: "an apple cultivar developed by growers at Tohoku Research Station",
      },
    },
}

Though this example is nested at most 2 levels deep, the input may be more than 2 levels deep. When rendered, the component should display the nested object legibly, with each word shown beside its definition and each subobject indented beyond its enclosing object. The rendered component is pictured below:

The rendered object
The rendered object

Starter Code

Here is some code to get you started:

import React, { useState } from "react";

function App() {
  const [nestedObjected, setNestedObject] = useState({
    taxi: "a car licensed to transport passengers in return for payment of a fare",
    food: {
      sushi:
        "a traditional Japanese dish of prepared rice accompanied by seafood and vegetables",
      apple: {
        Honeycrisp:
          "an apple cultivar developed at the MAES Horticultural Research Center",
        Fuji: "an apple cultivar developed by growers at Tohoku Research Station",
      },
    },
  });

  return (
    <div style={{ margin: "auto", width: "70%", paddingTop: 40 }}>
      <DisplayNested nestedObjected={nestedObjected} />
    </div>
  );
}

const DisplayNested = ({ nestedObjected }) => {
  return (
    // YOUR CODE HERE
  );
};

export default App;

Solution

First, the description of an arbitrarily nested object should cue you into using an approach that relies on recursion. Of course, it is possible to replicate a recursive function iteratively (for example, by making use of a stack), but a recursive function is most often the cleanest solution. This problem also tests the fundamental task of mapping over an array.

const DisplayNested = ({ nestedObjected }) => {
  return (
    <>
      {Object.entries(nestedObjected).map(([key, value]) => {
        if (typeof value === "object") {
          return (
            <>
              <p>{`${key}: `}</p>
              <div style={{ paddingLeft: 50 }}>
                <DisplayNested nestedObjected={value} />
              </div>
            </>
          );
        } else {
          return <p>{`${key}: ${value}`}</p>;
        }
      })}
    </>
  );
};

In the solution above, I start by enumerating the prop’s key/value pairs using Object.entries(), and I call map() on the returned array. I pass to map() an arrow function that destructures each key/value pair and, if the value is an object, displays the key and recurs with the subobject. If the value is not an object (ie if the object is a definition string), I simply display the key/value pair separated by a colon. Notably, if the function must recur, I return the result of the recursive call in a <div> with padding to its left so as to indent the nested object.


useState