2

I have this Array

[
  {
    id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc",
    description: "Response #1",
    user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
    responses: [
      {
        id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007",
        description: "Response #2",
        media: "b414e44f-7371-4cef-b0d9-d240e55b0ed1.jpg",
        user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
      }
    ]
  },
  {
    id: "d8271620-9937-4815-bd35-acad62d85f53",
    description: "Response #3",
    user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
    responses: [
      {
        id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca",
        description: "Response #4",
        user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
      }
    ]
  }
]

And I want to rename the properties to

[
  {
    id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc",
    name: "User — Response #1",
    children: [
      {
        id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007",
        name: "User — Response #2"
      }
    ]
  },
  {
    id: "d8271620-9937-4815-bd35-acad62d85f53",
    name: "User — Response #3",
    children: [
      {
        id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca",
        name: "User — Response #4",
      }
    ]
  }
]

I've tried to solve this with map and recursion

function mapArray(array) {
  return array.map(({ id, description, user: { name }, responses }) => {
    if (responses !== undefined) {
      return mapArray(responses);
    }

    return {
      id,
      name: `${name} — ${description}`,
      children: responses
    };
  });
}

But it the array becomes nested and the children is undefined.

[
  [
    {
      id: '69442cb1-7de7-4f2d-9c8b-d6689fa1d007',
      name: 'User — Response #2',
      children: undefined
    }
  ],
  [
    {
      id: '05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca',
      name: 'User — Response #4',
      children: undefined
    }
  ]
]

Please note that the responses have indefinite depth.

Where did I mess up? Thanks

1
  • should you not do responses = mapArray(responses) inside your if condition? Commented Sep 1, 2021 at 3:10

3 Answers 3

1

You are very close. Only 1 line change inside the if conditions should fix it.

function mapArray(array) {
  return array.map(({ id, description, user: { name }, responses }) => {
    if (responses !== undefined) {
      responses = mapArray(responses);
    }

    return {
      id,
      name: `${name} — ${description}`,
      children: responses
    };
  });
}
Sign up to request clarification or add additional context in comments.

Comments

1

Samridh diagnosed the issue and gave you a useful fix. If you're looking for a slightly more declarative version of the same idea, you could write the function like this:

const mapArray  = (array) => array .map (
  ({id, description, user: {name}, responses}) => ({
    id,
    name: `${name} - ${description}`,
    ...(responses ? {children: mapArray (responses)} : {})
  })
)

const input = [{id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc", description: "Response #1", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}, responses: [{id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007", description: "Response #2", media: "b414e44f-7371-4cef-b0d9-d240e55b0ed1.jpg", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}}]}, {id: "d8271620-9937-4815-bd35-acad62d85f53", description: "Response #3", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}, responses: [{id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca", description: "Response #4", user: {id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User"}}]}]

console .log (mapArray (input))
.as-console-wrapper {max-height: 100% !important; top: 0}

2 Comments

This is neater. Samridh version still left the object to exist even if it doesn't have any value and left an undefined. Thank you scott!
Note though that there's also a strong argument in favor of a consistent interface. While the undefined could well be problematic, you might also consider something like children: (responses ? mapArray (responses) : []) to include an empty array in that case. It might save much special-casing in later steps.
0

Might me a little ugly but is an alternate. Also Array.map() returns an array so it is obvious for it to be nested.

var obj = [
  {
    id: "2b077c3c-9d3a-48ba-9217-f5d3d28c2dfc",
    description: "Response #1",
    user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
    responses: [
      {
        id: "69442cb1-7de7-4f2d-9c8b-d6689fa1d007",
        description: "Response #2",
        media: "b414e44f-7371-4cef-b0d9-d240e55b0ed1.jpg",
        user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
      }
    ]
  },
  {
    id: "d8271620-9937-4815-bd35-acad62d85f53",
    description: "Response #3",
    user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" },
    responses: [
      {
        id: "05acce0a-8f7e-4ccd-9bbc-3337e4faa8ca",
        description: "Response #4",
        user: { id: "3ae5967a-cdfa-4047-aff9-b0c95d2d4da4", name: "User" }
      }
    ]
  }
];

var newObj = [];

obj.forEach(({ id, description: name, user: children }) => {
  newObj.push({ id, name, children: [children] });
});

console.log(JSON.stringify(newObj, null, 2));
.as-console-wrapper {
  max-height: 100% !important;
}

Comments

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.