Skip to content

Commit

Permalink
Added new methods flattenObject and expandObject
Browse files Browse the repository at this point in the history
  • Loading branch information
adrenalin committed Apr 19, 2021
1 parent 1df27f2 commit 1d625d1
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 1 deletion.
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ exports.castToArray = require('./lib/castToArray')
exports.castObjectAsArray = require('./lib/castObjectAsArray')
exports.copyObject = require('./lib/copyObject')
exports.errors = require('./lib/errors')
exports.flattenObject = require('./lib/flattenObject')
exports.getClassName = require('./lib/getClassName')
exports.getRandomString = require('./lib/getRandomString')
exports.getPath = require('./lib/getPath')
exports.getValue = require('./lib/getValue')
exports.expandObject = require('./lib/expandObject')
exports.httpBuildQuery = require('./lib/httpBuildQuery')
exports.intersection = require('./lib/intersection')
exports.isEqual = require('./lib/isEqual')
Expand Down
45 changes: 45 additions & 0 deletions lib/expandObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const isObject = require('./isObject')
const setValue = require('./setValue')

/**
* Expand a flattened object. This method unpacks values flattened with
* flattenObject
*
* Example:
*
* ```
* expandObject({
* {
* 'foo.bar.value': true
* 'foo.array': ['foo', 'bar']
* }
* })
* ```
*
* will outpout
*
* ```
* {
* foo: {
* bar: {
* value: true
* },
* array: ['foo', 'bar'],
* }
* }
* ```
*
* @param { object } input Object to expand
*/
module.exports = function expandObject (input) {
if (!isObject(input)) {
return input
}

const value = {}
for (const key in input) {
setValue(value, key, input[key])
}

return value
}
58 changes: 58 additions & 0 deletions lib/flattenObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const isObject = require('./isObject')
const getValue = require('./getValue')

/**
* Flatten an object. This is a serialization method that takes an object and
* flattens it into a single-level object with deep keys joined with a dot.
*
* Example:
*
* ```
* flattenObject({
* foo: {
* bar: {
* value: true
* },
* array: ['foo', 'bar'],
* }
* })
* ```
*
* will outpout
*
* ```
* {
* 'foo.bar.value': true
* 'foo.array': ['foo', 'bar']
* }
* ```
*
* @param { object } input Object tree to flatten
*/
module.exports = function flattenObject (input) {
if (!isObject(input)) {
return input
}

const values = {}

const traversePath = (path) => {
const p = path.join('.')
const v = getValue(input, p)

if (isObject(v)) {
for (const k in v) {
traversePath([...path, k])
}
return
}

values[p] = v
}

for (const k in input) {
traversePath([k])
}

return values
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "helpers.js",
"version": "0.19.1",
"version": "0.20.0",
"description": "Miscellaneous helpers",
"main": "index.js",
"scripts": {
Expand Down
39 changes: 39 additions & 0 deletions tests/expandObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const expect = require('expect.js')
const expandObject = require('../lib/expandObject')
const flattenObject = require('../lib/flattenObject')

describe('lib/expandObject', () => {
it('should return non-objects as they were', (done) => {
expect(expandObject(null)).to.eql(null)
expect(expandObject(undefined)).to.eql(undefined)
expect(expandObject(1.23)).to.eql(1.23)
expect(expandObject('foo')).to.eql('foo')
expect(expandObject(['foo', 'bar'])).to.eql(['foo', 'bar'])
done()
})

it('should expand an object', (done) => {
const source = {
'foo.bar': 'foo',
'foo.array': ['foo', 'bar'],
'foo.nested.deep.object': true
}

const value = expandObject(source)
expect(value).to.eql({
foo: {
bar: 'foo',
array: [
'foo',
'bar'
],
nested: {
deep: {
object: true
}
}
}
})
done()
})
})
36 changes: 36 additions & 0 deletions tests/flattenObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const expect = require('expect.js')
const flattenObject = require('../lib/flattenObject')

describe('lib/flattenObject', () => {
it('should return non-objects as they were', (done) => {
expect(flattenObject(null)).to.eql(null)
expect(flattenObject(undefined)).to.eql(undefined)
expect(flattenObject(1.23)).to.eql(1.23)
expect(flattenObject('foo')).to.eql('foo')
expect(flattenObject(['foo', 'bar'])).to.eql(['foo', 'bar'])
done()
})

it('should flatten a deep object', (done) => {
const source = {
foo: {
bar: 'foo',
array: [
'foo',
'bar'
],
nested: {
deep: {
object: true
}
}
}
}

const value = flattenObject(source)
expect(value['foo.bar']).to.eql(source.foo.bar)
expect(value['foo.array']).to.eql(source.foo.array)
expect(value['foo.nested.deep.object']).to.eql(true)
done()
})
})

0 comments on commit 1d625d1

Please sign in to comment.