Skip to content

Commit

Permalink
feat(utils): add object utils
Browse files Browse the repository at this point in the history
  • Loading branch information
ysfscream committed Nov 14, 2023
1 parent d64ee91 commit 6ddc2d7
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changeset/fuzzy-games-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@emqx/shared-ui-utils': patch
---

Add object utils functions
18 changes: 18 additions & 0 deletions packages/utils/lib/__test__/objectUtils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { flattenObject, unflattenObject } from '../objectUtils'
import { describe, it, expect } from 'vitest'

describe('flattenObject', () => {
it('should correctly flatten a nested object', () => {
const input = { a: { b: { c: 1 } } }
const output = flattenObject(input)
expect(output).toEqual({ 'a.b.c': 1 })
})
})

describe('unflattenObject', () => {
it('should correctly unflatten an object', () => {
const input = { 'a.b.c': 1 }
const output = unflattenObject(input)
expect(output).toEqual({ a: { b: { c: 1 } } })
})
})
17 changes: 0 additions & 17 deletions packages/utils/lib/__test__/utils.test.ts

This file was deleted.

5 changes: 1 addition & 4 deletions packages/utils/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
export function testUtils(word?: string) {
console.log('test ------> utils')
return `Hello ${word}`
}
export * from './objectUtils'
49 changes: 49 additions & 0 deletions packages/utils/lib/objectUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Flattens a nested object into a single-level object with dot-separated keys.
* @param obj - The object to flatten.
* @param prefix - An optional array of keys to use as a prefix for the flattened keys.
* @param current - An optional object to use as the initial flattened object.
* @returns The flattened object.
* Example: { a: { b: c: 1 } } => { 'a.b.c': 1 }
*/
export const flattenObject = (
obj: { [key: string]: any },
prefix: any[] = [],
current: { [key: string]: any } = {},
) => {
if (typeof obj === 'object' && !Array.isArray(obj) && obj !== null) {
for (const key of Object.keys(obj)) {
flattenObject(obj[key], prefix.concat(key), current)
}
} else {
current[prefix.join('.')] = obj
}
return current
}

/**
* Converts a flattened object to a nested object.
* @param obj - The flattened object to convert.
* @returns The nested object.
* Example: { 'a.b.c': 1 } => { a: { b: { c: 1 } } }
*/
export const unflattenObject = (obj: { [key: string]: any }) => {
if (Object(obj) !== obj && !Array.isArray(obj)) return obj
const regex = /\.?([^.[\]]+)|\[(\d+)\]/g
const resultholder: { [key: string]: any } = {}
try {
for (const p in obj) {
let current = resultholder
let prop = ''
let m: any
while ((m = regex.exec(p))) {
current = current[prop] || (current[prop] = m[2] ? [] : {})
prop = m[2] || m[1]
}
current[prop] = obj[p]
}
} catch (error) {
console.error(error)
}
return resultholder[''] || resultholder
}
6 changes: 4 additions & 2 deletions packages/utils/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { testUtils } from '../lib'
import { flattenObject, unflattenObject } from '../lib'

testUtils()
console.log('Output of flattenObject function: ', flattenObject({ a: { b: { c: 1 } } }))

console.log('Output of unflattenObject function: ', unflattenObject({ 'a.b.c': 1 }))

0 comments on commit 6ddc2d7

Please sign in to comment.