Blog
flattenObjectKeys() function in Refine source code.

flattenObjectKeys() function in Refine source code.

In this article, we will review a function, flattenObjectKeys, in Refine source code.

const isNested = (obj: any) => typeof obj === "object" && obj !== null;
const isArray = (obj: any) => Array.isArray(obj);

export const flattenObjectKeys = (obj: any, prefix = "") => {
  if (!isNested(obj)) {
    return {
      [prefix]: obj,
    };
  }

  return Object.keys(obj).reduce(
    (acc, key) => {
      const currentPrefix = prefix.length ? `${prefix}.` : "";

      if (isNested(obj[key]) && Object.keys(obj[key]).length) {
        if (isArray(obj[key]) && obj[key].length) {
          obj[key].forEach((item: unknown[], index: number) => {
            Object.assign(
              acc,
              flattenObjectKeys(item, `${currentPrefix + key}.${index}`),
            );
          });
        } else {
          Object.assign(acc, flattenObjectKeys(obj[key], currentPrefix + key));
        }
        // Even if it's a nested object, it should be treated as a key as well
        acc[currentPrefix + key] = obj[key];
      } else {
        acc[currentPrefix + key] = obj[key];
      }
      return acc;
    },
    {} as Record<string, unknown>,
  );
};

This code snippet is picked from the file shown in the below image:

This is recursive function that calls it self to create an object with flattened keys. I was going to copy this over and provide a sample object but I found that such an example already exists in the test case.

it("should flatten an object with nested objects and arrays", () => {
    const obj = {
      a: 1,
      b: {
        c: 2,
        d: [3, 4],
      },
      e: {
        f: {
          g: 5,
        },
      },
    };

    const flattenedObj = flattenObjectKeys(obj);

    expect(flattenedObj).toEqual({
      a: 1,
      b: {
        c: 2,
        d: [3, 4],
      },
      "b.c": 2,
      "b.d": [3, 4],
      "b.d.0": 3,
      "b.d.1": 4,
      e: {
        f: {
          g: 5,
        },
      },
      "e.f": {
        g: 5,
      },
      "e.f.g": 5,
    });
  });

You get the idea, right? the object below:

{
    a: 1,
    b: {
      c: 2,
      d: [3, 4],
    },
    e: {
      f: {
        g: 5,
      },
    },
};

gets flattened to something like below:

{
  a: 1,
  b: {
    c: 2,
    d: [3, 4],
  },
  "b.c": 2,
  "b.d": [3, 4],
  "b.d.0": 3,
  "b.d.1": 4,
  e: {
    f: {
      g: 5,
    },
  },
  "e.f": {
    g: 5,
  },
  "e.f.g": 5,
}

For more test cases, check out this file — flatten-object-keys/index.spec.ts

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com

My Github —  https://github.com/ramu-narasinga

My website —  https://ramunarasinga.com

My Youtube channel —  https://www.youtube.com/@thinkthroo

Learning platform —  https://thinkthroo.com

Codebase Architecture —  https://app.thinkthroo.com/architecture

Best practices —  https://app.thinkthroo.com/best-practices

Production-grade projects —  https://app.thinkthroo.com/production-grade-projects

References:

  1. https://github.com/refinedev/refine/blob/main/packages/core/src/definitions/helpers/flatten-object-keys/index.ts
We use cookies
We use cookies to ensure you get the best experience on our website. For more information on how we use cookies, please see our cookie policy.

By clicking "Accept", you agree to our use of cookies.

Learn more