Aggregate data to get desired output

I’m trying to aggregate data to create the array with objects where keys are going to be directories and inside of them will be files. I would like to achieve that kind of structure:

  const output = [
    {
      directory1: [
        {
          ...filecontent,
        },
        {
          ...filecontent,
        },
      ],
    },
    {
      directory2: [
        {
          ...filecontent,
        },
        {
          ...filecontent,
        },
      ],
    },
  ];

I try to do it with reduce, I get proper directory but somehow cannot process data to get desired output

 const output = files.reduce((acc: any[], file) => {
      const directory = getDirectory(file.uri);
      if (Object.keys(acc).includes(directory)) {
        acc[directory].push(file)
      } else {
        acc.push({ [directory]: file });
      }
      return acc;
    }, []);

>Solution :

There might be a better way to do that that involves only iterating over the file array once.

But a simpler solution that is easier to read and maintain is to aggregate your data like this:

const output = {
  directory1: [
    {
      ...filecontent,
    },
    {
      ...filecontent,
    },
  ],
  directory2: [
    {
      ...filecontent,
    },
    {
      ...filecontent,
    },
  ]
}

You can accomplish this by doing this:

const initialOutput = files.reduce((acc, file) => {
  const directory = getDirectory(file.uri)
  if (!output[directory]) {
    acc[directory] = [file]
  } else {
    acc[directory].push(file)
  }
  return acc
}, {})

Then afterwards convert it to the format that you want like this:

const formattedOutput = [];

for (const key in initialOutput) {
  if (initialOutput.hasOwnProperty(key)) {
    const newObject = {};
    newObject[key] = initialOutput[key];
    formattedOutput.push(newObject);
  }
}

This iterates over your files and then your aggregated output which might be less performant if that matters a lot to you, but it works.

Leave a Reply