Skip to content

Instantly share code, notes, and snippets.

@holmberd
Last active April 13, 2024 11:52
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save holmberd/945375f099cbb4139e37fef8055bc430 to your computer and use it in GitHub Desktop.
Save holmberd/945375f099cbb4139e37fef8055bc430 to your computer and use it in GitHub Desktop.
Dynamically create nested level groups by properties in Javascript

Dynamically create nested level groups by properties in Javascript

Code

/**
 * Creates nested groups by object properties.
 * `properties` array nest from highest(index = 0) to lowest level.
 *
 * @param {String[]} properties
 * @returns {Object}
 */
function nestGroupsBy(arr, properties) {
  properties = Array.from(properties);
  if (properties.length === 1) {
    return groupBy(arr, properties[0]);
  }
  const property = properties.shift();
  var grouped = groupBy(arr, property);
  for (let key in grouped) {
    grouped[key] = nestGroupsBy(grouped[key], Array.from(properties));
  }
  return grouped;
}

/**
 * Group objects by property.
 * `nestGroupsBy` helper method.
 *
 * @param {String} property
 * @param {Object[]} conversions
 * @returns {Object}
 */
function groupBy(conversions, property) {
  return conversions.reduce((acc, obj) => {
    let key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

Example

var products = [
  { id: 1, name: 'p1', country: 'US', platform: 'win'},
  { id: 2, name: 'p1', country: 'US', platform: 'win'},
  { id: 3, name: 'p1', country: 'GB', platform: 'mac'},
  { id: 4, name: 'p1', country: 'US', platform: 'mac'},
  { id: 5, name: 'p2', country: 'US', platform: 'win'},
  { id: 6, name: 'p2', country: 'GB', platform: 'win'},
  { id: 7, name: 'p3', country: 'US', platform: 'mac'},
];

const groups = nestGroupsBy(products, ['name', 'country', 'platform']);
console.log(groups);
/* 
output:
{ p1: 
  { US: 
    { win: [
        {id: 1, name: 'p1', country: 'US', platform: 'win'},
        {id: 2, name: 'p1', country: 'US', platform: 'win'},          
      ], 
      mac: [
        {id: 4, name: 'p1', country: 'US', platform: 'mac'},
      ] 
     }, 
     GB: { win: [{ id: 3, name: 'p1', country: 'GB', platform: 'mac'}] } },
  p2: { US: { win: [Array] }, GB: { win: [Array] } },
  p3: { US: { mac: [Array] } } }  
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment