#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <numeric>
class DataStream {
public:
DataStream(const std::vector<std::map<std::string, std::string>>& data) : data(data) {}
DataStream project(std::function<std::map<std::string, std::string>(const std::map<std::string, std::string>&)> projectFunc) const {
std::vector<std::map<std::string, std::string>> projectedData;
for (const auto& entry : data) {
projectedData.push_back(projectFunc(entry));
}
return DataStream(projectedData);
}
DataStream filter(std::function<bool(const std::map<std::string, std::string>&)> testFunc) const {
std::vector<std::map<std::string, std::string>> filteredData;
std::copy_if(data.begin(), data.end(), std::back_inserter(filteredData), testFunc);
return DataStream(filteredData);
}
double aggregate(const std::string& key, std::function<double(const std::vector<std::string>&)> aggFunc) const {
std::vector<std::string> values;
for (const auto& entry : data) {
if (entry.find(key) != entry.end()) {
values.push_back(entry.at(key));
}
}
return aggFunc(values);
}
void printData() const {
for (const auto& entry : data) {
for (const auto& pair : entry) {
std::cout << pair.first << ": " << pair.second << ", ";
}
std::cout << std::endl;
}
}
private:
std::vector<std::map<std::string, std::string>> data;
};
// Example usage
int main() {
DataStream ds({
{ {"name", "Alice"}, {"age", "25"}, {"profession", "Engineer"}, {"salary", "70000"} },
{ {"name", "Bob"}, {"age", "30"}, {"profession", "Doctor"}, {"salary", "120000"} },
{ {"name", "Carol"}, {"age", "35"}, {"profession", "Artist"}, {"salary", "50000"} },
{ {"name", "David"}, {"age", "40"}, {"profession", "Engineer"}, {"salary", "90000"} }
});
// Step 1: Project the data to include only 'name', 'age', and 'salary'
DataStream projectedDs = ds.project([](const std::map<std::string, std::string>& entry) {
return std::map<std::string, std::string>{{"name", entry.at("name")}, {"age", entry.at("age")}, {"salary", entry.at("salary")}};
});
// Step 2: Filter the projected data to include only those with age > 30
DataStream filteredDs = projectedDs.filter([](const std::map<std::string, std::string>& entry) {
return std::stoi(entry.at("age")) > 30;
});
// Step 3: Aggregate the filtered data to compute the average salary
double averageSalary = filteredDs.aggregate("salary", [](const std::vector<std::string>& salaries) {
double sum = 0;
for (const auto& salary : salaries) {
sum += std::stoi(salary);
}
return sum / salaries.size();
});
std::cout << averageSalary << std::endl; // Outputs: 70000.0
return 0;
}