Skip to content

Instantly share code, notes, and snippets.

@indiesquidge
Created March 9, 2018 02:35
Show Gist options
  • Save indiesquidge/699f31ce6f3d92e4b038ea44afcc4333 to your computer and use it in GitHub Desktop.
Save indiesquidge/699f31ce6f3d92e4b038ea44afcc4333 to your computer and use it in GitHub Desktop.
Generate an object tree given an object keyed by category hierarchy levels.
const rawCategories = {
'hierarchical_categories.level_1': {
'Beverages': 349,
'Coffee & Tea': 4,
'Deli': 35
},
'hierarchical_categories.level_2': {
'Beverages > Energy & Sports Drinks': 54,
'Beverages > Juice & Nectars': 111,
'Deli > Cheeses': 30
},
'hierarchical_categories.level_3': {
'Beverages > Juice & Nectars > Orange Juice': 35,
'Beverages > Juice & Nectars > Apple Juice': 35,
'Deli > Cheeses > Specialty Cheeses': 3
}
}
const desiredCategoryTree = {
'Beverages': {
count: 349,
children: {
'Energy & Sports Drinks': {
count: 54,
children: null
},
'Juices & Nectars': {
count: 111,
children: {
'Orange Juice': {
count: 35,
children: null
},
'Apple Juice': {
count: 35,
children: null
}
}
}
}
},
'Coffee & Tea': {
count: 4,
children: null
},
'Deli': {
count: 35,
children: {
'Cheeses': {
count: 30,
children: {
'Specialty Cheeses': {
count: 3,
children: null
}
}
}
}
}
}
const actualCategoryTree = generateCategoryTree(rawCategories)
expect(actualCategoryTree).toEqual(desiredCategoryTree)
function generateCategoryTree (categories = {}, level = 1) {
return Object.keys(categories).reduce((next, category) => {
const categoriesArray = category.split(' > ')
const parent = categoriesArray[level - 1]
const child = categoriesArray[level]
const parentLineage = Object.keys(categories).find(key =>
key.endsWith(parent)
)
const childLineage = Object.keys(categories).find(key =>
key.endsWith(child)
)
if (!next[parent] || !child) {
return {
...next,
[parent]: {
value: categories[child ? childLineage : parentLineage],
children: null
}
}
}
const children = Object.keys(
categories
).reduce((nextCategories, category) => {
if (
category.split(' > ').length > level &&
category.startsWith(parentLineage)
) {
nextCategories[category] = categories[category]
}
return nextCategories
}, {})
return {
...next,
[parent]: {
...next[parent],
children: generateCategoryTree(children, level + 1)
}
}
}, {})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment