Skip to content

Instantly share code, notes, and snippets.

@kirbysayshi
Last active May 14, 2019 15:31
Show Gist options
  • Save kirbysayshi/2ea881ebe643458311f4 to your computer and use it in GitHub Desktop.
Save kirbysayshi/2ea881ebe643458311f4 to your computer and use it in GitHub Desktop.
flatten an object into a single depth using string keys
require('tap-browser-color')();
var test = require('tape');
test('it flattens!', function(t) {
var input = {
users: [
{ name: 'name1', id: 1, image: { '64x64': 'http://1' } },
{ name: 'name2', id: 2, image: { '64x64': 'http://2' } }
],
errors: [ new Error('err1') ],
success: true
}
var expected = {
'users.0.name': 'name1',
'users.0.id': 1,
'users.0.image.64x64': 'http://1',
'users.1.name': 'name2',
'users.1.id': 2,
'users.1.image.64x64': 'http://2',
'users.length': 2,
'errors.0.columnNumber': input.errors[0].columnNumber,
'errors.0.fileName': input.errors[0].fileName,
'errors.0.lineNumber': input.errors[0].lineNumber,
'errors.0.message': input.errors[0].message,
'errors.0.stack': input.errors[0].stack,
'errors.length': 1,
'success': true
}
t.deepEqual(flatten(input), expected);
t.end();
})
function flatten(obj, opt_out, opt_paths) {
var out = opt_out || {};
var paths = opt_paths || [];
return Object.getOwnPropertyNames(obj).reduce(function(out, key) {
paths.push(key);
if (typeof obj[key] === 'object') {
flatten(obj[key], out, paths);
} else {
out[paths.join('.')] = obj[key];
}
paths.pop();
return out;
}, out)
}
@yangmillstheory
Copy link

yangmillstheory commented Nov 4, 2016

Here's one that doesn't requiring mutating an array. I was asked this in an phone screen today (and bombed the implementation):

const pathDelimiter = '.'

function flatten(source, flattened = {}, keySoFar = '') {
  function getNextKey(key) {
    return `${keySoFar}${keySoFar ? pathDelimiter : ''}${key}`
  }
  if (typeof source === 'object') {
    for (const key in source) {
      flatten(source[key], flattened, getNextKey(key))
    }
  } else {
    flattened[keySoFar] = source
  }
  return flattened
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment