Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Given an array of orders, find the top 3 customers with the
- * highest lifetime value (those that spent the most over time).
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Start with the initial implementation.
- //
- // One approach to solving this task would be to create
- // a map of the customerId and a sum of their order totals.
- // Convert this map to an array so we can sort the orders
- // from highest to lowest. Display the top three customers.
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- const orders = [
- {orderId: 1, customerId: 1, total: 10.50},
- {orderId: 2, customerId: 1, total: 11.50},
- {orderId: 3, customerId: 2, total: 12.50},
- {orderId: 4, customerId: 3, total: 130.50},
- {orderId: 5, customerId: 7, total: 24.50},
- {orderId: 6, customerId: 2, total: 64.50},
- {orderId: 7, customerId: 4, total: 40.50},
- {orderId: 8, customerId: 4, total: 29.50},
- {orderId: 9, customerId: 6, total: 61.50},
- {orderId: 10, customerId: 7, total: 110.00}
- ];
- //Build a temporary table to track total orders for a customer.
- let orderTotalsMap = {};
- for (let i = 0; i < orders.length; i++) {
- let order = orders[i];
- if (orderTotalsMap[order.customerId] === undefined) {
- orderTotalsMap[order.customerId] = order.total;
- } else {
- orderTotalsMap[order.customerId] += order.total;
- }
- }
- //Convert the map to an array and sort by the aggregated order total.
- const keysArr = Object.keys(orderTotalsMap);
- let orderTotalsArr = [];
- for (let i = 0; i < keysArr.length; i++) {
- const totals = {
- customerId: keysArr[i],
- total: orderTotalsMap[keysArr[i]]
- }
- orderTotalsArr.push(totals);
- }
- orderTotalsArr.sort(function (a, b) {
- return b.total - a.total;
- });
- const topThreeCustomers = orderTotalsArr.slice(0, 3);
- console.log('The top three customers:', topThreeCustomers);
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // It's difficult to understand what's going on in the
- // example above. With some refactoring, this can be much
- // more legible.
- //
- // To fulfill our requirements, we must:
- // 1. Get the lifetime value for each customer.
- // 2. Sort by the total amount and return the top 3 customers.
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- const orders = [
- {orderId: 1, customerId: 1, total: 10.50},
- {orderId: 2, customerId: 1, total: 11.50},
- {orderId: 3, customerId: 2, total: 12.50},
- {orderId: 4, customerId: 3, total: 130.50},
- {orderId: 5, customerId: 7, total: 24.50},
- {orderId: 6, customerId: 2, total: 64.50},
- {orderId: 7, customerId: 4, total: 40.50},
- {orderId: 8, customerId: 4, total: 29.50},
- {orderId: 9, customerId: 6, total: 61.50},
- {orderId: 10, customerId: 7, total: 110.00}
- ];
- //Get order totals for each customer.
- const getCustomerLifetimeValues = (acc, order) => {
- const {customerId, total} = order;
- if (acc[customerId] === undefined) {
- acc[customerId] = {customerId, total}
- } else {
- acc[customerId].total += total;
- }
- return acc;
- }
- //Comparator for sorting by total.
- const comparator = (a, b) => b.total - a.total;
- //Now, for the code that matters! Let's worry less about "how this works" and more about the "why we need it".
- let lifetimeValuesObj = orders.reduce(getCustomerLifetimeValues, {});
- let topThreeCustomers = Object.values(lifetimeValuesObj).sort(comparator).slice(0, 3);
- console.log('The top three customers:', topThreeCustomers);
- // For this solution, we are able to make reasable assumptions about the code because it's much easier to understand.
- // By looking at lines 102 - 103, we know that the code will calculate the totals for each customer and provide top
- // three customers by order totals. We didn't have to study the implementation to determine what is going on. Sweet!
Add Comment
Please, Sign In to add comment