Last active
March 13, 2018 21:29
-
-
Save beardedtim/9a846648f041ec8f5e205724d413ebe8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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