๐Ÿ“ฆ waynehamadi / nested-functions

โ˜… 0 stars โ‘‚ 0 forks ๐Ÿ‘ 0 watching
๐Ÿ“ฅ Clone https://github.com/waynehamadi/nested-functions.git
HTTPS git clone https://github.com/waynehamadi/nested-functions.git
SSH git clone git@github.com:waynehamadi/nested-functions.git
CLI gh repo clone waynehamadi/nested-functions
Merwane Hamadi Merwane Hamadi implement tests dee56b3 1 years ago ๐Ÿ“ History
๐Ÿ“‚ master View all commits โ†’
๐Ÿ“ src
๐Ÿ“ test
๐Ÿ“„ .babelrc
๐Ÿ“„ .gitignore
๐Ÿ“„ jest.config.js
๐Ÿ“„ package.json
๐Ÿ“„ README.md
๐Ÿ“„ tsconfig.json
๐Ÿ“„ README.md

Nested Object Flattener

This project demonstrates two approaches to flatten nested objects with underscore notation: a custom implementation and one using the established flat library.

Installation

# Clone the repository
git clone git@github.com:waynehamadi/nested-functions.git
cd nested-functions

# Install dependencies
npm install

Usage

Custom Implementation

The custom implementation (src/flatten.ts) flattens nested objects with specific rules:

  • Uses underscore (\_) as delimiter
  • Handles arrays with index notation
  • Strict conflict handling:
  • Root level fields take precedence in simple conflicts
  • Throws errors for complex nested conflicts
  • Omits empty arrays and objects
import { flattenObject } from "./src/flatten";

const input = {
  person: {
    name: "John",
    age: 30,
  },
  addresses: [
    {
      street: "Main St",
    },
  ],
};

const flattened = flattenObject(input);
// Result:
// {
//   person_name: "John",
//   person_age: 30,
//   addresses_0_street: "Main St"
// }

Recommended Approach: Using flat library

Instead of using the custom implementation, it's recommended to use the established flat library:

import flatten from "flat";

const input = {
  person: {
    name: "John",
    age: 30,
  },
};

const flattened = flatten(input, { delimiter: "_" });

Running Tests

# Run all tests
npm test

# Run only custom implementation tests
npm test flatten.test.ts

# Run only flat library tests
npm test better-flatten.test.ts

Key Differences Between Implementations

  • Conflict Handling
// Custom throws error:
const input = {
  user: {
    profile: { data: "nested" },
    profile_data: "mid-level",
  },
  user_profile_data: "top-level",
};

// This throws error with custom implementation
flattenObject(input); // Error: "Conflicting field names: user_profile_data appears multiple times"

// flat just overwrites:
flatten(input, { delimiter: "_" }); // Works fine, last value wins

  • Empty Structures
const input = {
  emptyArr: [],
  emptyObj: {},
};

// Custom removes empty structures
flattenObject(input); // {}

// flat keeps them
flatten(input, { delimiter: "_" }); // { emptyArr: [], emptyObj: {} }

  • Type Safety
// Custom is strictly typed
type Primitive = string | number | boolean | null | undefined;
type NestedObject = {
  [key: string]: Primitive | NestedObject | Array<any>;
};

// flat is more permissive with types

Why Use flat?

While the custom implementation demonstrates interesting edge cases and strict type safety, for production use you should use the flat library because:

  • No need to maintain custom code
  • Better tested in production environments
  • Regular updates and bug fixes
  • Community support
  • Better performance

Development

# Run tests in watch mode
npm run test:watch

# Type checking
npm run type-check

License

ISC