Skip to content

Instantly share code, notes, and snippets.

@beardedtim
Last active March 13, 2018 21:29
Show Gist options
  • Select an option

  • Save beardedtim/9a846648f041ec8f5e205724d413ebe8 to your computer and use it in GitHub Desktop.

Select an option

Save beardedtim/9a846648f041ec8f5e205724d413ebe8 to your computer and use it in GitHub Desktop.
// Input
const data = [
{
calcFieldValue: 3,
id: '50346a2e-8421-e811-a2bc-000c29878c3f',
idFieldValue: null,
primaryCurrencyCalcFieldValue: 4,
productFolder: 'Personal',
productTypeName: 'DDAs',
fields: [],
relationshipTypes: [{
id: '5901e243-db0c-e811-a2ba-000c29878c3f',
name: 'Primary'
}]
},
{
calcFieldValue: 3,
id: '50346a2e-8421-e811-a2bc-000c29878c3f',
idFieldValue: null,
primaryCurrencyCalcFieldValue: 4,
productFolder: 'Personal',
productTypeName: 'DDAs',
fields: [],
relationshipTypes: [{
id: '5901e243-db0c-e811-a2ba-000c29878c3f',
name: 'Primary'
}]
},
{
calcFieldValue: 3,
id: '50346a2f-8421-e811-a2bc-000c29878c3f',
idFieldValue: null,
primaryCurrencyCalcFieldValue: 4,
productFolder: 'Personal',
productTypeName: 'DDAs',
fields: [],
relationshipTypes: [{
id: '5901e242-db0c-e811-a2ba-000c29878c3f',
name: 'Primaries'
}]
}
]
/*
TARGET
[ {
id: '5901e243-db0c-e811-a2ba-000c29878c3f', // relationshipType.id
name: 'Primary', // relationshipType.name
count: 1, // number of products with this relationshipType
groups: [{
name: 'Personal', // productFolder
total: 4, // sum of all product primaryCurrencyCalcFieldValues in this group
products: [{
name: 'DDAs', // product type name
id: '50346a2e-8421-e811-a2bc-000c29878c3f', // product id
fields: [] // whatever dynamic fields the API gave us
}]
}],
}]
*/
// Given our `data` array, return a productHash
// EXAMPLE:
// [{ id: 1 }] => { 1: { id: 1 } }
const createProductHashFromData = reduce((acc, curr) => ({
...acc,
[curr.id]: curr
}), {})
const createRelationshipHash = reduce((acc, curr) => {
const { relationshipTypes, id } = curr
const ids = relationshipTypes.map(pick(['id','name']))
const newVal = { ...acc }
ids.forEach(({ id: relId, name }) => {
if (has(relId, acc)) {
newVal[relId] = {
...newVal[relId],
list: newVal[relId].list.concat(id)
}
} else {
newVal[relId] = {
name,
id,
list: [id]
}
}
})
return newVal
}, {})
const productHash = createProductHashFromData(data)
const relationshipHash = createRelationshipHash(data);
// Grabs the id, fields, and productTypeName
// and changes productTypeName key to name
const getProudctForGroup = ({ productTypeName: name, id, fields }) => ({
id,
fields,
name,
})
// Transform a list of Product ( main object in input array )
// into the groups needed per spec
const createGroups = reduce((acc, curr) => {
// we are calling the productFolder key the groupId
// because we like it
const groupId = curr.productFolder
// If at some point before now we have seen this
// specific group id
if (has(groupId, acc)) {
// We know that we already have some "state" to update
return ({
// copy everything previously
...acc,
// and at the key equal to groupId
[groupId]: {
// copy over the previous values
...acc[groupId],
// update it's count by adding the correct key
count: acc[groupId].count + curr.primaryCurrencyCalcFieldValue,
// and we want to create a new array and add a special form of
// Product, made for our Group
products: acc[groupId].products.concat(getProudctForGroup(curr))
}
})
}
// If we are here, it means that we have never
// seen this specific groupId
return ({
// so we just copy over all the previous "state"
...acc,
// and then set the groupId key
[groupId]: {
// to the general structure of our Product
count: curr.primaryCurrencyCalcFieldValue,
products: [getProudctForGroup(curr)],
name: groupId
}
})
}, {})
// Creates the final shape of the `groups` key
// given a previously transformed `relationship`
const getGroupHash = compose(
values,
createGroups
)
// This is where we transform the data into our final shape
keys(relationshipHash)
.map(relId => {
// we take the relationship from the relationshipHash
const relationship = prop(relId, relationshipHash)
// and we create our final relationship shape
return ({
id: relId,
name: relationship.name,
count: relationship.list.length,
// We need to transform `groups` after this but
// we can make that an easier problem by grabbing
// the value from productHash that is at the key
// at each index
//
// EXAMPLE:
// productHash = { 'a': { id: 'a' } }
// ['a'] => [({ id: 'a' })]
groups: relationship.list.map(flip(prop)(productHash))
})
})
.map(({ groups, ...rest }) => ({
// Once we get everything right
...rest,
// we can transform groups for final consumer
groups: getGroupHash(groups)
}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment