DEV Community

Varya Stepanova
Varya Stepanova

Posted on

2 1

Flatten array with JavaScript reduce function

Nested structures are useful for managing and editing. But when it comes to representation in UI, it might
not be trivial to iterate through all the deep levels. Often happens, that it is more useful to have
a flat structure which probably preserves the depth of the items. In JavaScript, easiest way to transform such structure is
reduce method.

Making juice with reduce

Say, we have a nested structure representing the parts of a design system. This is a list of categories
with underlying item which, in turn, may have subitems.

export const parts = [
  {
    title: "Visual language",
    parts: [
      {
        title: "Color",
        parts: ["Palettes", "Contrast", "Meaning", "Swatches"],
      },
      {
        title: "Typography",
        parts: ["Hierarchy", "Weights / types", "Web fonts", "Baseline grid"],
      },
      "Photography",
    ],
  },
  {
    title: "UI elements",
    category: true,
    parts: [
      "Paragraph",
      "Block quote",
      "Headers (H1 - H6)",
      "Lists",
      "Links",
      {
        title: "Buttons",
        parts: [
          "Primary",
          "Secondary",
          "Button groups",
          "Menu buttons",
        ],
      },
      "Slider",
    ],
  },
];
Enter fullscreen mode Exit fullscreen mode

Instead of going deeper and deeper, it's worth to flatten the structure with the help of reduce function, and then
iterate through the new structure.

const flatten = (obj, depth, currentDepth = 0) => {
  const array = Array.isArray(obj) ? obj : [obj];
  return array.reduce((acc, value) => {
    acc.push({
      title: value.title || value,
      depth: currentDepth,
    });
    if (value.parts) {
      acc = acc.concat(flatten(value.parts, depth, currentDepth + 1));
    }
    return acc;
  }, []);
};

const partsFlattened = parts.map((category) => {
  const categoryFlattened = {
    parts: flatten(category.parts),
    title: category.title,
    category: category.category,
  };
  return categoryFlattened;
});
Enter fullscreen mode Exit fullscreen mode

This code fallens the given structure as the following.

[
   {
      "category":"undefined",
      "parts":[
         {
            "depth":0,
            "title":"Color"
         },
         {
            "depth":1,
            "title":"Palettes"
         },
         {
            "depth":1,
            "title":"Contrast"
         },
         {
            "depth":1,
            "title":"Meaning"
         },
         {
            "depth":1,
            "title":"Swatches"
         },
         {
            "depth":0,
            "title":"Typography"
         },
         {
            "depth":1,
            "title":"Hierarchy"
         },
         {
            "depth":1,
            "title":"Weights / types"
         },
         {
            "depth":1,
            "title":"Web fonts"
         },
         {
            "depth":1,
            "title":"Baseline grid"
         },
         {
            "depth":0,
            "title":"Photography"
         }
      ],
      "title":"Visual language"
   },
   {
      "category":true,
      "parts":[
         {
            "depth":0,
            "title":"Paragraph"
         },
         {
            "depth":0,
            "title":"Block quote"
         },
         {
            "depth":0,
            "title":"Headers (H1 - H6)"
         },
         {
            "depth":0,
            "title":"Lists"
         },
         {
            "depth":0,
            "title":"Links"
         },
         {
            "depth":0,
            "title":"Buttons"
         },
         {
            "depth":1,
            "title":"Primary"
         },
         {
            "depth":1,
            "title":"Secondary"
         },
         {
            "depth":1,
            "title":"Button groups"
         },
         {
            "depth":1,
            "title":"Menu buttons"
         },
         {
            "depth":0,
            "title":"Slider"
         }
      ],
      "title":"UI elements"
   }
]
Enter fullscreen mode Exit fullscreen mode

Lately, the flat structure can be used if, for instance, you need to output the items similarly but
provide additional CSS classes depending on the depth of the items. Run the demo
to see how it can work.

Image source: https://macwright.org/2015/01/03/reduce-juice.html
Originally published at Varya.me

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay