I want to create a dynamic hierarchy based on my groups and rollup sum to top level, also if I am providing a large amount of data browser is getting hang.
I have the below data:
var data = [ { "country":"Spain", "orderNumber":10394, "year":2018, "countrycode":"es", "quantityOrdered":30, "priceEach":60.28, "productName":"1950's Chicago Surface Lines Streetcar", "productLine":"Trains", "sortkey":3, "productCode":"S32_3207", "month":"March", "extendedPrice":1808.4, "orderDate":"2018-03-15 00:00:00" }, { "country":"France", "orderNumber":10395, "year":2018, "countrycode":"fr", "quantityOrdered":32, "priceEach":105.33, "productName":"1972 Alfa Romeo GTA", "productLine":"Classic Cars", "sortkey":3, "productCode":"S10_4757", "month":"March", "extendedPrice":3370.56, "orderDate":"2018-03-17 00:00:00" }, { "country":"France", "orderNumber":10395, "year":2018, "countrycode":"fr", "quantityOrdered":33, "priceEach":69.12, "productName":"2001 Ferrari Enzo", "productLine":"Classic Cars", "sortkey":3, "productCode":"S12_1108", "month":"March", "extendedPrice":2280.96, "orderDate":"2018-03-17 00:00:00" }, { "country":"France", "orderNumber":10395, "year":2018, "countrycode":"fr", "quantityOrdered":46, "priceEach":123.76, "productName":"Diamond T620 Semi-Skirted Tanker", "productLine":"Trucks and Buses", "sortkey":3, "productCode":"S50_1392", "month":"March", "extendedPrice":5692.96, "orderDate":"2018-03-17 00:00:00" }, { "country":"France", "orderNumber":10395, "year":2018, "countrycode":"fr", "quantityOrdered":45, "priceEach":199.49, "productName":"1962 City of Detroit Streetcar", "productLine":"Trains", "sortkey":3, "productCode":"S50_1514", "month":"March", "extendedPrice":8977.05, "orderDate":"2018-03-17 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":33, "priceEach":185.13, "productName":"1969 Ford Falcon", "productLine":"Classic Cars", "sortkey":3, "productCode":"S12_3891", "month":"March", "extendedPrice":6109.29, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":33, "priceEach":159.81, "productName":"1903 Ford Model A", "productLine":"Vintage Cars", "sortkey":3, "productCode":"S18_3140", "month":"March", "extendedPrice":5273.73, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":24, "priceEach":89.75, "productName":"Collectable Wooden Train", "productLine":"Trains", "sortkey":3, "productCode":"S18_3259", "month":"March", "extendedPrice":2154, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":45, "priceEach":105.32, "productName":"1904 Buick Runabout", "productLine":"Vintage Cars", "sortkey":3, "productCode":"S18_4522", "month":"March", "extendedPrice":4739.4, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":49, "priceEach":116.75, "productName":"18th century schooner", "productLine":"Ships", "sortkey":3, "productCode":"S24_2011", "month":"March", "extendedPrice":5720.75, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":27, "priceEach":83.2, "productName":"1912 Ford Model T Delivery Wagon", "productLine":"Vintage Cars", "sortkey":3, "productCode":"S24_3151", "month":"March", "extendedPrice":2246.4, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":37, "priceEach":90.57, "productName":"1940 Ford Delivery Sedan", "productLine":"Vintage Cars", "sortkey":3, "productCode":"S24_3816", "month":"March", "extendedPrice":3351.09, "orderDate":"2018-03-23 00:00:00" }, { "country":"USA", "orderNumber":10396, "year":2018, "countrycode":"us", "quantityOrdered":39, "priceEach":66.67, "productName":"The Schooner Bluenose", "productLine":"Ships", "sortkey":3, "productCode":"S700_1138", "month":"March", "extendedPrice":2600.13, "orderDate":"2018-03-23 00:00:00" }, { "country":"France", "orderNumber":10397, "year":2018, "countrycode":"fr", "quantityOrdered":32, "priceEach":80.55, "productName":"The Mayflower", "productLine":"Ships", "sortkey":3, "productCode":"S700_1938", "month":"March", "extendedPrice":2577.6, "orderDate":"2018-03-28 00:00:00" } ]
I have created below function but its not working properly
var groups = ['country', 'productLine', 'month']; // this can be dynamic var sum = ['priceEach']; // this can be dynamic function createGroup (groups, data, sum, childNode) { let [primaryGroup, ...rest] = groups; let groupedData = data.reduce((acc, current) => { let chunk = { 'Name': current[primaryGroup], [primaryGroup]: current[primaryGroup], [sum]: data.filter(item => item[primaryGroup] === current[primaryGroup]) .map(el => el[sum]) .reduce((total, current) => total + current), ...(rest.length > 0 ? {[groups[childNode]]: createGroup(rest, data, sum,childNode+1 )} : {}) } acc.push(chunk) return acc }, []) .reduce((acc, current) => { const x = acc.find(item => item[primaryGroup] === current[primaryGroup]) return !x ? acc.concat([current]) : acc }, []) return groupedData; } const tree = createGroup(groups,data,sum, 1);
Required below sample result (I haven’t included other country but I need all)
[ { "country":[ { "Name":"Spain", "priceEach":60.28, "productline":[ { "Name":"Trains", "priceEach":60.28, "month":[ { "Name":"March", "priceEach":60.28 } ] } ] } ] }, { "country":[ { "Name":"France", "priceEach":578.25, "productline":[ { "Name":"Classic Cars", "priceEach":174.45, "month":[ { "Name":"March", "priceEach":174.45 } ] }, { "Name":"Trucks and Buses", "priceEach":123.76, "month":[ { "Name":"March", "priceEach":123.76 } ] }, { "Name":"Trains", "priceEach":199.49, "month":[ { "Name":"April", "priceEach":199.49 } ] }, { "Name":"Ships", "priceEach":80.55, "month":[ { "Name":"June", "priceEach":80.55 } ] } ] } ] } ]
Advertisement
Answer
Well, it is probably hangs
because of O(n log n)
(you iterate the same data
over and over).
Note: priceEach
is static in this solution, but you can redesign the recursive function
function createGroup(groups, i, data, parent){ //Take current group var group = groups[i]; var nGroup = groups[i+1]; // No more group, stop recursivity if (!group) return parent; // Now, let's reduce by current group //FIX: We need to add an empty item to force the reduce method if(data.length == 1) { data.push({priceEach:0}); } var root = data.reduce((prev, next) => { //First time, add prev value if(parent.length == 0) { var item = {}; item[group] = { "Name": prev[group], "priceEach": prev.priceEach } //Next group? if(nGroup){ item[group][nGroup] = createGroup(groups, i+1, [prev], []); } parent.push(item); } //Check if we need to reduce for(var item of parent){ if(item[group].Name == next[group]) { item[group].priceEach += next.priceEach; //Next group? if(nGroup){ item[group][nGroup] = createGroup(groups, i+1, [prev, next], item[group][nGroup]); } return parent; } } //We did not reduce, so add next as item if(next[group]) { var item = {}; item[group] = { "Name": next[group], "priceEach": next.priceEach } //Next group? if(nGroup){ item[group][nGroup] = createGroup(groups, i+1, [next], []); } parent.push(item); } return parent; }); return root; } createGroup(["country", "productLine", "month"], 0, data, []);
If country, productLine, month
are static, you can run the classic way