Applying Data Filtering and Aggregation in C++ with an User Management System

Introduction

Welcome to today's lesson on applying data filtering and aggregation in a real-world scenario using a user management system. We'll start by building a foundational structure that can handle basic user operations. Then, we'll expand it by introducing more advanced functionalities that allow filtering and aggregating user data.

Starter Task Methods

In our starter task, we will implement a class that manages basic operations on a collection of user data, specifically handling adding new users, retrieving user profiles, and updating user profiles.

Here are the starter task methods:

  • bool add_user(std::string user_id, int age, std::string country, bool subscribed) - adds a new user with the specified attributes. Returns true if the user was added successfully and false if a user with the same user_id already exists.
  • std::optional<UserProfile> get_user(std::string user_id) - returns the user's profile if the user exists; otherwise, returns std::nullopt.
  • bool update_user(std::string user_id, std::optional<int> age, std::optional<std::string> country, std::optional<bool> subscribed) - updates the user's profile based on non-optional parameters. Returns true if the user exists and was updated, false otherwise.

To store the user data, we will define a UserProfile custom struct.

Starter Task Implementation

Here is the implementation of our starter task in C++:

#include <iostream>
#include <string>
#include <map>
#include <optional>

struct UserProfile {
    int age;
    std::string country;
    bool subscribed;
};

class UserManager {
public:
    bool add_user(const std::string& user_id, int age, const std::string& country, bool subscribed) {
        if (users.find(user_id) != users.end()) {
            return false;
        }
        users[user_id] = UserProfile{age, country, subscribed};
        return true;
    }

    std::optional<UserProfile> get_user(const std::string& user_id) {
        if (users.find(user_id) != users.end()) {
            return users[user_id];
        }
        return std::nullopt;
    }

    bool update_user(const std::string& user_id, std::optional<int> age, std::optional<std::string> country, std::optional<bool> subscribed) {
        if (users.find(user_id) == users.end()) {
            return false;
        }
        if (age) {
            users[user_id].age = age.value();
        }
        if (country) {
            users[user_id].country = country.value();
        }
        if (subscribed) {
            users[user_id].subscribed = subscribed.value();
        }
        return true;
    }

private:
    std::map<std::string, UserProfile> users;
};

// Example usage
int main() {
    UserManager um;
    std::cout << std::boolalpha;
    std::cout << um.add_user("u1", 25, "USA", true) << std::endl;  // true
    std::cout << um.add_user("u2", 30, "Canada", false) << std::endl;  // true
    std::cout << um.add_user("u1", 22, "Mexico", true) << std::endl;  // false

    if (auto user = um.get_user("u1")) {
        std::cout << user->age << std::endl;  // 25
    }

    std::cout << um.update_user("u1", 26, std::nullopt, std::nullopt) << std::endl;  // true
    std::cout << um.update_user("u3", 19, "UK", false) << std::endl;  // false

    return 0;
}

This implementation covers all our starter methods. Let's move forward and introduce more complex functionalities.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal