Welcome to our lesson on mastering data aggregation and data streams with JSON formatting in JavaScript. In this lesson, we'll start by building a basic sales records aggregator. Then, we'll extend its functionality to handle more complex operations such as filtering, data aggregation, and formatting. By the end of this session, you'll be able to manage and format data streams efficiently.
To begin, we'll implement a basic sales record aggregator. Here are the methods we'll be focusing on:
add_sale(sale_id, amount)
- Adds a sale record with a unique identifiersale_id
and anamount
. If a sale with the samesale_id
already exists, it updates the amount.get_sale(sale_id)
- Retrieves the sale amount associated with thesale_id
. If the sale does not exist, it returnsundefined
.delete_sale(sale_id)
- Deletes the sale record with the givensale_id
. Returnstrue
if the sale was deleted andfalse
if the sale does not exist.
Are these methods clear so far? Great! Let's now look at how we would implement them.
Here is the complete code for the starter task:
JavaScript1class SalesAggregator { 2 constructor() { 3 this.sales = {}; // Initialize an empty object to store sales records. 4 } 5 6 add_sale(sale_id, amount) { 7 this.sales[sale_id] = amount; // Add or update the sale with the provided sale_id and amount. 8 } 9 10 get_sale(sale_id) { 11 // Retrieve and return the sale amount for the given sale_id, or undefined if it doesn't exist. 12 return this.sales[sale_id] !== undefined ? this.sales[sale_id] : undefined; 13 } 14 15 delete_sale(sale_id) { 16 if (sale_id in this.sales) { 17 delete this.sales[sale_id]; // Remove the sale record. 18 return true; // Return true indicating the sale was deleted. 19 } 20 return false; // Return false if the sale_id doesn't exist. 21 } 22} 23 24// Example Usage 25const aggregator = new SalesAggregator(); 26 27// Add sales 28aggregator.add_sale('001', 100.50); 29aggregator.add_sale('002', 200.75); 30 31// Get sale 32console.log(aggregator.get_sale('001')); // Output: 100.5 33 34// Delete sale 35console.log(aggregator.delete_sale('002')); // Output: true 36console.log(aggregator.get_sale('002')); // Output: undefined
Explanation:
- The
constructor
method initializes an empty object to store sales records. - The
add_sale
method adds a new sale or updates the amount for an existing sale ID. - The
get_sale
method retrieves the amount for a given sale ID or returnsundefined
if the sale does not exist. - The
delete_sale
method removes the sale record for the given sale ID or returnsfalse
if the sale does not exist.
Now that we have our basic aggregator, let's extend it to include more advanced functionalities.
To increase the complexity and usefulness of our sales aggregator, we'll adjust some existing methods and introduce some new methods and functionalities involving JSON.
-
add_sale(sale_id, amount, date)
- Adds or updates a sale record with a unique identifiersale_id
,amount
, and adate
in the format "YYYY-MM-DD". -
aggregate_sales(min_amount = 0)
- Returns an object with the total number of sales and the total amount of sales where the sale amount is abovemin_amount
. The object format looks like this:JavaScript1{ 2 total_sales: 0, 3 total_amount: 0.0 4}
-
format_sales(min_amount = 0)
- Returns the sales data, filtered bymin_amount
, formatted as JSON. Includes aggregated sales statistics in the output. -
get_sales_in_date_range(start_date, end_date)
- Retrieves all sales that occurred within the given date range, inclusive. Each sale includessale_id
,amount
, anddate
.
Let's implement these methods step-by-step.
We'll first modify the add_sale
method to accept a date.
JavaScript1add_sale(sale_id, amount, date) { 2 // Add or update the sale with the provided sale_id, amount, and date. 3 this.sales[sale_id] = { amount: amount, date: date }; 4}
This ensures that each sale record includes a date in addition to the amount.
Now, we create the aggregate_sales
method:
JavaScript1aggregate_sales(min_amount = 0) { 2 let total_sales = 0; 3 let total_amount = 0.0; 4 for (const sale of Object.values(this.sales)) { 5 if (sale.amount > min_amount) { 6 total_sales += 1; // Increment total sales count. 7 total_amount += sale.amount; // Add to the total amount. 8 } 9 } 10 return { total_sales: total_sales, total_amount: total_amount }; // Return the aggregated results. 11} 12 13// Create an instance of SalesAggregator 14const aggregator = new SalesAggregator(); 15 16// Add sales with date 17aggregator.add_sale('001', 100.50, '2023-01-01'); 18aggregator.add_sale('002', 200.75, '2023-01-15'); 19 20// Aggregate sales 21console.log(aggregator.aggregate_sales(50)); 22// Output: { total_sales: 2, total_amount: 301.25 }
This method iterates through the sales and sums up those that exceed the min_amount
.
Next, we'll create the format_sales
method to output data in JSON format.
JavaScript1format_sales(min_amount = 0) { 2 // Filter and format sales data based on min_amount. 3 const filtered_sales = Object.entries(this.sales) 4 .filter(([_, sale]) => sale.amount > min_amount) 5 .map(([sale_id, sale]) => ({ sale_id: sale_id, amount: sale.amount, date: sale.date })); 6 7 // Aggregate sales statistics. 8 const statistics = this.aggregate_sales(min_amount); 9 10 // Combine sales data and statistics into the final result. 11 const result = { 12 sales: filtered_sales, 13 statistics: statistics 14 }; 15 return JSON.stringify(result); // Convert the result to JSON. 16} 17 18// Format sales to JSON 19console.log(aggregator.format_sales(50)); 20// Output: '{"sales":[{"sale_id":"001","amount":100.5,"date":"2023-01-01"},{"sale_id":"002","amount":200.75,"date":"2023-01-15"}],"statistics":{"total_sales":2,"total_amount":301.25}}'
This function formats the sales data as JSON and includes aggregated statistics.
Finally, let's implement the get_sales_in_date_range
method:
JavaScript1get_sales_in_date_range(start_date, end_date) { 2 const start = new Date(start_date); 3 const end = new Date(end_date); 4 return Object.entries(this.sales) 5 .filter(([_, sale]) => { 6 const sale_date = new Date(sale.date); 7 return sale_date >= start && sale_date <= end; // Check if the sale is within the date range. 8 }) 9 .map(([sale_id, sale]) => { 10 return { sale_id: sale_id, ...sale }; // Return the sale data. 11 }); 12} 13 14// Get sales in date range 15console.log(aggregator.get_sales_in_date_range('2023-01-01', '2023-12-31')); 16// Output: [{ sale_id: '001', amount: 100.5, date: '2023-01-01' }, { sale_id: '002', amount: 200.75, date: '2023-01-15' }]
This method retrieves all sales within the specified date range.
Congratulations! You've now extended a basic sales aggregator to an advanced one capable of filtering, aggregating, and formatting data in JSON. These skills are crucial for handling data streams efficiently, especially when dealing with large datasets. Feel free to experiment with similar challenges to reinforce your understanding. Well done, and see you in the next lesson!