diff --git a/README.md b/README.md index 2e4cb3c..b6a5c2f 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,34 @@ unflatten({ Use a custom delimiter for (un)flattening your objects, instead of `.`. +### keyname + +Use a custom `function` to flatten the keyname. By default, the `delimiter` is inserted between `prev` and `next` + +Here's an example that uses a colon (':') to prefix and delimit the keyname + +````javascript +var o = { + hello: { + world: { + again: 'good morning' +}}} + +flatten(o, { keyname: function(prev, next) { + return prev + ? prev + ':' + next + : ':' + next +}}) + +// { +// ':hello:world:again': 'good morning' +// } +```` + +### keynames + +Use a custom `function` to unflatten the keyname. It returns an array of key names. This is the inverse of [keyname](#keyname). By default, the `delimiter` is used to [split](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) the name. + ### safe When enabled, both `flat` and `unflatten` will preserve arrays and their diff --git a/index.js b/index.js index e22351e..87399b3 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,14 @@ function flatten(target, opts) { var delimiter = opts.delimiter || '.' var maxDepth = opts.maxDepth + + function flattenKeyname(prev, key) { + return prev + ? prev + delimiter + key + : key + } + + var keyname = opts.keyname || flattenKeyname; var output = {} function step(object, prev, currentDepth) { @@ -23,9 +31,7 @@ function flatten(target, opts) { type === "[object Array]" ) - var newKey = prev - ? prev + delimiter + key - : key + var newKey = keyname(prev, key) if (!isarray && !isbuffer && isobject && Object.keys(value).length && (!opts.maxDepth || currentDepth < maxDepth)) { @@ -53,6 +59,12 @@ function unflatten(target, opts) { return target } + function unflattenKeyname(key) { + return key.split(delimiter) + } + + var keynames = opts.keynames || unflattenKeyname; + // safely ensure that the key is // an integer. function getkey(key) { @@ -66,7 +78,7 @@ function unflatten(target, opts) { } Object.keys(target).forEach(function(key) { - var split = key.split(delimiter) + var split = keynames(key) var key1 = getkey(split.shift()) var key2 = getkey(split[0]) var recipient = result diff --git a/test/test.js b/test/test.js index 1261921..fdceedb 100644 --- a/test/test.js +++ b/test/test.js @@ -103,6 +103,22 @@ suite('Flatten', function() { }) }) + test('Custom keyname', function() { + assert.deepEqual(flatten({ + hello: { + world: { + again: 'good morning' + } + } + }, { + keyname: function(prev, key) { + return prev ? prev + ':' + key : ':' + key + } + }), { + ':hello:world:again': 'good morning' + }) + }) + test('Empty Objects', function() { assert.deepEqual(flatten({ hello: { @@ -223,6 +239,22 @@ suite('Unflatten', function() { })) }) + test('Custom keynames', function() { + assert.deepEqual({ + hello: { + world: { + again: 'good morning' + } + } + }, unflatten({ + ':hello:world:again': 'good morning' + }, { + keynames: function(key) { + return key.substr(1).split(':') + } + })) + }) + test('Overwrite', function() { assert.deepEqual({ travis: {