The approach below uses flatMap to flatten tags acquired through map. Finally, use the spread operator to assign the values from tag and the feature's name.

const result = _.flatMap(features, ({ name, tags }) =>
  _.map(tags, tag => ({ name, ...tag }))
);

const features = [{
    'name': 'feature1',
    'tags': [{
      'weight': 10,
      'tagName': 't1'
    }, {
      'weight': 20,
      'tagName': 't2'
    }, {
      'weight': 30,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature2',
    'tags': [{
      'weight': 40,
      'tagName': 't1'
    }, {
      'weight': 5,
      'tagName': 't2'
    }, {
      'weight': 70,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature3',
    'tags': [{
      'weight': 50,
      'tagName': 't1'
    }, {
      'weight': 2,
      'tagName': 't2'
    }, {
      'weight': 80,
      'tagName': 't3'
    }]
  }
];

const result = _.flatMap(features, ({ name, tags }) =>
  _.map(tags, tag => ({ name, ...tag }))
);

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Here's a plain javascript solution that uses Array#reduce and Array#map with the help of Array#concat to flatten the array.

const result = features.reduce(
  (result, { name, tags }) => result
    .concat(tags.map(tag => ({ name, ...tag }))), 
  []
);

const features = [{
    'name': 'feature1',
    'tags': [{
      'weight': 10,
      'tagName': 't1'
    }, {
      'weight': 20,
      'tagName': 't2'
    }, {
      'weight': 30,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature2',
    'tags': [{
      'weight': 40,
      'tagName': 't1'
    }, {
      'weight': 5,
      'tagName': 't2'
    }, {
      'weight': 70,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature3',
    'tags': [{
      'weight': 50,
      'tagName': 't1'
    }, {
      'weight': 2,
      'tagName': 't2'
    }, {
      'weight': 80,
      'tagName': 't3'
    }]
  }
];

const result = features.reduce(
  (result, { name, tags }) => result
    .concat(tags.map(tag => ({ name, ...tag }))), 
  []
);

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Answer from ryeballar on Stack Overflow
Top answer
1 of 1
43

The approach below uses flatMap to flatten tags acquired through map. Finally, use the spread operator to assign the values from tag and the feature's name.

const result = _.flatMap(features, ({ name, tags }) =>
  _.map(tags, tag => ({ name, ...tag }))
);

const features = [{
    'name': 'feature1',
    'tags': [{
      'weight': 10,
      'tagName': 't1'
    }, {
      'weight': 20,
      'tagName': 't2'
    }, {
      'weight': 30,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature2',
    'tags': [{
      'weight': 40,
      'tagName': 't1'
    }, {
      'weight': 5,
      'tagName': 't2'
    }, {
      'weight': 70,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature3',
    'tags': [{
      'weight': 50,
      'tagName': 't1'
    }, {
      'weight': 2,
      'tagName': 't2'
    }, {
      'weight': 80,
      'tagName': 't3'
    }]
  }
];

const result = _.flatMap(features, ({ name, tags }) =>
  _.map(tags, tag => ({ name, ...tag }))
);

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Here's a plain javascript solution that uses Array#reduce and Array#map with the help of Array#concat to flatten the array.

const result = features.reduce(
  (result, { name, tags }) => result
    .concat(tags.map(tag => ({ name, ...tag }))), 
  []
);

const features = [{
    'name': 'feature1',
    'tags': [{
      'weight': 10,
      'tagName': 't1'
    }, {
      'weight': 20,
      'tagName': 't2'
    }, {
      'weight': 30,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature2',
    'tags': [{
      'weight': 40,
      'tagName': 't1'
    }, {
      'weight': 5,
      'tagName': 't2'
    }, {
      'weight': 70,
      'tagName': 't3'
    }]
  },
  {
    'name': 'feature3',
    'tags': [{
      'weight': 50,
      'tagName': 't1'
    }, {
      'weight': 2,
      'tagName': 't2'
    }, {
      'weight': 80,
      'tagName': 't3'
    }]
  }
];

const result = features.reduce(
  (result, { name, tags }) => result
    .concat(tags.map(tag => ({ name, ...tag }))), 
  []
);

console.log(result);
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

🌐
Dustin John Pfister
dustinpfister.github.io › 2018 › 08 › 12 › lodash_flatten
The lodash _.flatten method for flatting down a multi dimensional array | Dustin John Pfister at github pages
December 9, 2021 - Flatten can be used to flatten down an array of arrays into a single array, thus making it a method that can be thought of as a reversal of _.chunk. With that said the lodash chunk method will do the inversion of flatten which is to break an ...
🌐
GeeksforGeeks
geeksforgeeks.org › lodash-_-flatten-method
Lodash _.flatten() Method - GeeksforGeeks
September 2, 2024 - Lodash is a JavaScript library that works on the top of underscore.js. Lodash helps in working with arrays, strings, objects, numbers etc. The Lodash.flatten() method is used to flatten the array to one level deep.
🌐
Lodash
lodash.com › docs
Lodash Documentation
The predicate is invoked with three ... over elements of collection from right to left. ... Creates a flattened array of values by running each element in collection thru iteratee and flattening the mapped results....
🌐
Tabnine
tabnine.com › home page › code › javascript › lodash
lodash.flatten JavaScript and Node.js code examples | Tabnine
/** * * @param appServer * @returns {Promise<[]|*>} */ async resolveAndInitRouters(appServer) { if (!appServer) { return; } this.appServer = appServer; const routerDescriptorResolvers = injectSync(this.moduleInjector, APP_ROUTER_DESCRIPTOR_RESOLVER); if (!routerDescriptorResolvers) { this.routers = []; return; } const routers = await Promise.all( toArray(routerDescriptorResolvers) .filter(Boolean) .filter(r => isFunction(r.resolve)) .map((r) => this._resolveRouter(r)) ); this.routers = flatten(routers); await this.initRouters(); } LoDashStatic.map · Creates an array of values by running each element in collection through iteratee. The iteratee is · LoDashStatic.isEmpty · Checks if value is empty. A value is considered empty unless it’s an arguments object, array, string ·
🌐
TecHighness
techighness.com › home › java script flatten deeply nested array of objects into single level array
JavaScript Flatten Deeply Nested Array of Objects Into Single Level Array - TecHighness
December 26, 2022 - Flat Array Object: { id: '23b9dbff', name: 'Jessie', age: 50 } // children reference removed Original Array Object: { id: '23b9dbff', name: 'Jessie', age: 50, children: [ { id: '5c0f3094', name: 'Peter', age: 20 }, { id: 'c1484221', name: 'Paul', age: 32, children: [Array] }, // still has children { id: '8a265c23', name: 'Hilda', age: 25 } ] } The above same thing can be done more precisely using lodash’s flatMapDeep method as follows:
🌐
Educative
educative.io › answers › what-is-the-flattendeep-method-in-lodash
What is the _.flattenDeep() method in Lodash?
The _.flattenDeep() method in Lodash is used to recursively flatten an array, that is, to flatten all the nested arrays completely.
🌐
GitHub
github.com › matteoantoci › lodash.flatten
GitHub - matteoantoci/lodash.flatten: Flatten / un-flatten nested objects · GitHub
A simple utility based on lodash to flatten and un-flatten nested objects/arrays.
Author   matteoantoci
Find elsewhere
🌐
GitHub
github.com › lodash › lodash › issues › 1228
Is there a functionality to flatten/deflatten an object? · Issue #1228 · lodash/lodash
May 25, 2015 - lodash / lodash Public · Notifications · You must be signed in to change notification settings · Fork 7.1k · Star 61.6k · New issueCopy link · New issueCopy link · Closed · Closed · Is there a functionality to flatten/deflatten an object?#1228 · Copy link · Labels · enhancementwontfix · moatazelmasry2 · opened · on May 25, 2015 · Issue body actions · Hi there, I have the following object/array of objects: Object1: { id: 2, balance: 130, 'Issue : { 'id': 1, 'currency': 'EUR' } }``` Object2: ```json { id: 2, balance: 130, 'Issue.id': 1, 'Issue.currency': 'EUR' } Is there a way to 'deflatten' object1 into object2 and flatten object2 into object1?
Published   May 25, 2015
Author   moatazelmasry2
🌐
TutorialsPoint
tutorialspoint.com › lodash › lodash_flattendeep.htm
Lodash - flatten method
Home Whiteboard Practice Code Graphing Calculator Online Compilers Articles Tools ... Python TechnologiesDatabasesComputer ProgrammingWeb DevelopmentJava TechnologiesComputer ScienceMobile DevelopmentBig Data & AnalyticsMicrosoft TechnologiesDevOpsLatest TechnologiesMachine LearningDigital MarketingSoftware QualityManagement Tutorials View All Categories ... Recursively flattens array. ... var _ = require('lodash'); var list = [1, [2], [4], 5, [[6]]]; var result = _.flattenDeep(list) console.log(result);
Top answer
1 of 3
3

You can create a recursive function (getSchema) that checks if a value (val) is an object (arrays included), iterate it with _.flatMap(), and collects the keys until it hits a value which is not an object. It then joins the collected keys and returns the string.

const getSchema = (val, keys = []) =>
  _.isObject(val) ? // if it's an object or array
    _.flatMap(val, (v, k) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys
    :
    keys.join('.') // return the joined keys

const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }

const result = getSchema(invoiceObject)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Without lodash, the main change is to use Object.entries() to get an array of [key, value] pairs, since Array.flatMap() can't iterate objects:

const getSchema = (val, keys = []) =>
  typeof val === 'object' && val !== null ? // if it's an object or array
    Object.entries(val) // get [key, value] pairs of object/array
      .flatMap(([k, v]) => getSchema(v, [...keys, k])) // iterate it and call fn with the value and the collected keys 
    :
    keys.join('.') // return the joined keys

const invoiceObject = { "AllowIPNPayment": false, "AllowOnlinePayment": false, "AllowOnlineCreditCardPayment": false, "AllowOnlineACHPayment": false, "domain": "QBO", "sparse": false, "Id": "16", "SyncToken": "1", "MetaData": { "CreateTime": "2020-03-25T15:10:40-07:00", "LastUpdatedTime": "2020-03-26T11:06:49-07:00" }, "CustomField": [{ "DefinitionId": "1", "Name": "Crew #", "Type": "StringType" }], "DocNumber": "1007", "TxnDate": "2020-03-03", "CurrencyRef": { "value": "USD", "name": "United States Dollar" }, "LinkedTxn": [{ "TxnId": "32", "TxnType": "Payment" }], "Line": [{ "Id": "1", "LineNum": 1, "Description": "Custom Design", "Amount": 750, "DetailType": "SalesItemLineDetail", "SalesItemLineDetail": { "ItemRef": { "value": "4", "name": "Design" }, "UnitPrice": 75, "Qty": 10, "TaxCodeRef": { "value": "NON" } } }, { "Amount": 750, "DetailType": "SubTotalLineDetail", "SubTotalLineDetail": {} } ], "TxnTaxDetail": { "TotalTax": 0 }, "CustomerRef": { "value": "13", "name": "uiool" }, "CustomerMemo": { "value": "Thank you for your business and have a great day!" }, "SalesTermRef": { "value": "3" }, "DueDate": "2020-04-02", "TotalAmt": 750, "ApplyTaxAfterDiscount": false, "PrintStatus": "NeedToPrint", "EmailStatus": "NotSet", "BillEmail": { "Address": "uiikoool" }, "Balance": 450 }

const result = getSchema(invoiceObject)

console.log(result)

2 of 3
1

inspired by the answer given in this post and understanding you just want to get the property-names, not values, you could do it like this. sorry, this uses plain javascript.

function flattenObjectToKeyArray(ob) {
  var toReturn = [];
  for (var prop in ob) {
    if (!ob.hasOwnProperty(prop)) continue;

    if ((typeof ob[prop]) == 'object' && ob[prop] !== null) {
      var flatObject = flattenObjectToKeyArray(ob[prop]);
      for (var idx = 0; idx < flatObject.length; idx++) {
        toReturn.push(prop + '.' + flatObject[idx]);
      }
    } else {
      toReturn.push(prop);
    }
  }
  return toReturn;
}
Top answer
1 of 4
13

You can simply use the npm package flat.

import flat from 'flat';

const array = [
  {
    a: 'a',
    b: {
      bb: 'bb',
    },
    c: {
      cc1: 'cc1',
      cc: {
        ccc: 'ccc',
        ccd: 'ccd',
      },
    },
  },
  // ...
];

const flattenedArray = array.map(flat);

/*
  flattenedArray === [
    {
      a: 'a',
      b.bb: 'bb',
      c.cc1: 'cc1',
      c.cc.ccc: 'ccc',
      c.cc.ccd: 'ccd',
    },
    // ...
  ]
*/

And if you want to implement it yourself, here's my implementation of flat:

const flat = (obj, concatenator = '.') => (
  Object.keys(obj).reduce(
    (acc, key) => {
      if (typeof obj[key] !== 'object' || !obj[key]) {
        return {
          ...acc,
          [key]: obj[key],
        };
      }

      const flattenedChild = flat(obj[key], concatenator);

      return {
        ...acc,
        ...Object.keys(flattenedChild).reduce((childAcc, childKey) => ({ ...childAcc, [`${key}${concatenator}${childKey}`]: flattenedChild[childKey] }), {}),
      };
    },
    {},
  )
);

const flattenedArray = array.map(o => flat(o));

Those solutions will work with any depth.

2 of 4
4

You can do this without lodash (or another library) by iterating over the keys of each item in the original array, checking their type, and further iterating over their internal keys, building new keys to hold the right values.

const array = [{
  id: 123,
  name: 'John',
  summary1: {
    count: 3,
    sum: 10
  },
  summary2: {
    count: 10,
    sum: 20
  }
}];


let newArray = array.map(item => {
  let newObj = {};

  Object.keys(item).forEach(key => {
    if (typeof item[key] === 'object') {
      Object.keys(item[key]).forEach(innerKey => {
        newObj[`${key}_${innerKey}`] = item[key][innerKey];
      });
    } else {
      newObj[key] = item[key];
    }
  });

  return newObj;
});

console.log(newArray);

Granted, this isn't necessarily very pretty or flexible (following your assumption of a single level deep).

🌐
GitHub
github.com › lodash › lodash › issues › 1724
_.flatten on array like objects · Issue #1724 · lodash/lodash
December 26, 2015 - Given that other Array methods like _.difference, _.intersection, _.uniq, & _.xor accept array-like values, would it be possible to allow _.flatten to work on array like objects?
Author   patak-dev
🌐
YouTube
youtube.com › watch
How to Flatten Nested Objects to Arrays with Lodash in JavaScript - YouTube
Learn how to effectively use Lodash's `toPairs()` and `flatMap()` to convert hierarchically structured JavaScript objects into flat arrays.---This video is b
Published   May 26, 2025
Views   0
🌐
CopyProgramming
copyprogramming.com › howto › flatten-an-nested-array-of-objects-using-lodash
Mastering Lodash Flatten: Objects, Nested Arrays, and 2026 Best Practices - Mastering lodash flatten objects nested arrays
February 19, 2026 - Lodash flatten functions like _.flattenDeep transform nested arrays into single-level arrays effortlessly. For objects and nested arrays of objects, combine Lodash utilities such as _.flatMap or custom recursions to achieve clean, performant results.
🌐
GitHub
github.com › lodash › lodash › issues › 48
Calling _.flatten on objects · Issue #48 · lodash/lodash
July 16, 2012 - Not sure if this is an actual issue since flatten is supposed to work on arrays only -- but it is a difference between lodash and underscore. If you try to flatten an object: _.flatten({name:['abc']}) In underscore you get: ['abc'] and i...
Author   idosela