Home > Software design >  Recursively Find and Add Them as an Array
Recursively Find and Add Them as an Array

Time:09-17

I have this kind of table (or data structure)

enter image description here

There is parentIdeaId that refers to the id in ideas table itself.

Here's my unstructured data (please bear in mind this is the existing data in the database, not data that is already as it is so I have to query this first under some condition)

[{
    "id": "1",
    "title": "Title 1",
    "parentIdeaId": null
},{
    "id": "2",
    "title": "Title 2",
    "parentIdeaId": 1
},{
    "id": "3",
    "title": "Title 3",
    "parentIdeaId": 2
},{
    "id": "4",
    "title": "Title 4",
    "parentIdeaId": null
}]

I also made a function to find the data (I'm using Prisma in my real code)

function find({ id }) {
  return prisma.idea.findUnique({
    where: {
      id
    }
  });
}

And a function to find the children

function responseIdeas({ parentIdeaId }) {
  return prisma.idea.findMany({
    where: {
      parentIdeaId
    }
  });
}

I want the data to be filtered only linked data (by their parentIdeaId) so if I query the id "1" the result would be

[{
    "id": "1",
    "title": "Title 1",
    "parentIdeaId": null
},{
    "id": "2",
    "title": "Title 2",
    "parentIdeaId": 1
}{
    "id": "3",
    "title": "Title 3",
    "parentIdeaId": 2
}]

The id: "4" isn't inserted because it's not related by its parent

Here's what I made:

const data = [
  {
    id: "1",
    title: "Title 1",
    parentIdeaId: null
  },
  {
    id: "2",
    title: "Title 2",
    parentIdeaId: 1
  },
  {
    id: "3",
    title: "Title 3",
    parentIdeaId: 2
  },
  {
    id: "4",
    title: "Title 4",
    parentIdeaId: null
  }
];

function find({ id }) {
  return data.find(e => e.id === id);
}

function responseIdeas({ parentIdeaId }) {
  return data.filter(e => e.parentIdeaId == parentIdeaId);
}

async function detail({ id }) {
  const findChildren = async ({ id }) => {
    const idea = await find({ id });
    const responses = await responseIdeas({ parentIdeaId: id });
    if (responses.length !== 0) {
      const resolveResponses = await Promise.all(
        responses.map(async ({ id }) => findChildren({ id }))
      );
      return [idea, ...resolveResponses];
    }
    return { ...idea };
  };

  return findChildren({ id });
}

async function run() {
  const result = await detail({ id: "1" });
  console.dir(result, { depth: null });
}

run();

But it ended up being like this

[
  {
    "id": "1",
    "title": "Title 1",
    "parentIdeaId": null
  },
  [
    {
      "id": "2",
      "title": "Title 2",
      "parentIdeaId": 1
    },
    {
      "id": "3",
      "title": "Title 3",
      "parentIdeaId": 2
    }
  ]
]

Where did I mess up? Thanks

CodePudding user response:

findChildren potentially returns an array of arrays due to the fact that your returning Promise.all() -> which is a array of promises and some of those promises can be arrays.

So you can use concat to merge the result into the main array e.g like this https://codesandbox.io/s/quizzical-sun-c4khx?file=/src/index.js

  • Related