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/@ramu-narasinga
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:
Subscribe to my newsletter
Read articles from Ramu Narasinga directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

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