Skip to content

[Edit] C++: unordered maps #7074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d0dd9bd
[Edit] SQL: DATEDIFF()
mamtawardhani May 21, 2025
9f5c19b
Update datediff.md
mamtawardhani May 21, 2025
c32e9f3
Merge branch 'Codecademy:main' into main
mamtawardhani May 23, 2025
4170ba2
Merge branch 'Codecademy:main' into main
mamtawardhani May 23, 2025
8325585
Merge branch 'Codecademy:main' into main
mamtawardhani May 26, 2025
8f6f8e8
Merge branch 'Codecademy:main' into main
mamtawardhani May 27, 2025
e4c54e8
Merge branch 'Codecademy:main' into main
mamtawardhani May 28, 2025
7b3b9c0
Merge branch 'Codecademy:main' into main
mamtawardhani May 29, 2025
27ecefd
Merge branch 'Codecademy:main' into main
mamtawardhani May 29, 2025
0392da4
Merge branch 'Codecademy:main' into main
mamtawardhani May 30, 2025
d550fa7
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 2, 2025
793be7d
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 3, 2025
2f03b61
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 3, 2025
25eb0ab
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 3, 2025
73e0e3b
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 4, 2025
44f4c63
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 5, 2025
545a8da
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 6, 2025
49d85cd
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 9, 2025
f488437
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 10, 2025
9b642e6
Merge branch 'Codecademy:main' into main
mamtawardhani Jun 11, 2025
64d19c6
[Edit] C++: unordered maps
mamtawardhani Jun 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 156 additions & 72 deletions content/cpp/concepts/unordered-map/unordered-map.md
Original file line number Diff line number Diff line change
@@ -1,134 +1,218 @@
---
Title: 'Unordered Maps'
Description: 'Unordered Maps are associative containers with elements with key-value pairs.'
Title: 'unordered_map'
Description: 'Stores data in key-value pairs using hash table implementation for fast lookups.'
Subjects:
- 'Computer Science'
- 'Game Development'
- 'Web Development'
Tags:
- 'Objects'
- 'OOP'
- 'Classes'
- 'Data Structures'
- 'Hash Maps'
- 'Map'
- 'STL'
CatalogContent:
- 'learn-c-plus-plus'
- 'paths/computer-science'
---

**`Unordered Maps`** are associative containers that have elements with key-value pairs. Unlike Maps, the pairs in Unordered Maps are not sorted by their keys. Each mapped value must have a unique key value.
The **`unordered_map`** is an associative container in C++ that stores data in key-value pairs, similar to a dictionary or hash table. Unlike the standard [`map`](https://www.codecademy.com/resources/docs/cpp/maps) container, `unordered_map` uses a hash table implementation that provides average constant-time complexity O(1) for search, insertion, and deletion operations. However, the elements are not stored in any particular sorted order, making it ideal for scenarios where fast access is more important than maintaining order.

## Syntax
The `unordered_map` is particularly useful in applications requiring frequent lookups, such as caching systems, database indexing, counting frequencies of elements, and implementing symbol tables in compilers. It excels in scenarios where you need to associate unique keys with values and perform rapid searches based on those keys.

An empty unordered map can be created by using the `unordered_map` keyword, declaring the data types of the key and value, and setting a `mapName`:
## Syntax

```pseudo
std::unordered_map<type1, type2> mapName;
std::unordered_map<key_type, value_type> map_name;
```

- `type1`: Date type of the key in the unordered_map.
- `type2`: Date type of the value in the unordered_map.
**Parameters:**

- `key_type`: The data type of the keys stored in the unordered_map
- `value_type`: The data type of the values associated with the keys
- `map_name`: The identifier name for the unordered_map instance

> **Note:** To use unordered_map, including the `unordered_map` library is necessary.
**Return value:**

## Examples
The `unordered_map` container itself does not return a value, but its member functions return various types depending on the operation (iterators, boolean values, references, etc.).

The below example shows how to use `unordered_map`.
## Example 1: Creating and Initializing

This example demonstrates the basic creation and initialization of an `unordered_map`:

```cpp
#include <iostream>
#include <unordered_map>
#include <string>

int main() {
std::unordered_map<std::string, int> myMap;

// Inserting elements
myMap["apple"] = 2;
myMap["banana"] = 5;
myMap["orange"] = 3;
// Create an empty unordered_map
std::unordered_map<int, std::string> colors;

// Initialize using initializer list
std::unordered_map<int, std::string> fruits = {
{1, "Apple"},
{2, "Banana"},
{3, "Orange"}
};

// Display the initialized map
std::cout << "Fruits map contains:" << std::endl;
for (const auto& pair : fruits) {
std::cout << pair.first << ": " << pair.second << std::endl;
}

// Iterating over elements
for (const std::pair<const std::string, int>& x : myMap) {
std::cout << x.first << " " << x.second << std::endl;
}
return 0;
return 0;
}
```

The output will be:
The output of this code is:

```shell
orange 3
banana 5
apple 2
Fruits map contains:
3: Orange
2: Banana
1: Apple
```

### Overriding Functions
This example shows how to create an empty `unordered_map` and initialize another with key-value pairs using an initializer list. The output displays the fruit IDs and names, demonstrating basic map creation and iteration.

## Example 2: Counting Character Frequencies

By default, keys are treated as `case-sensitive`, but this can be avoided, so they can be treated as `case-insensitive`. In the example below, the keys are treated as `case-insensitive`.
This example demonstrates using `unordered_map` to count the frequency of characters in a string, a common real-world application:

```cpp
#include <iostream>
#include <unordered_map>
#include <string>
#include <algorithm> // for std::max_element

struct CustomHash {
std::size_t operator()(const std::string & key) const {
// Custom hash: hash based on the length of the string
return key.length();
}
};
int main() {
std::string text = "programming";
std::unordered_map<char, int> charFreq;

struct CustomEqual {
bool operator()(const std::string & lhs,
const std::string & rhs) const {
// Custom equality: compare strings ignoring case
return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(),
[](char a, char b) {
return tolower(a) == tolower(b);
});
// Count frequency of each character
for (char c : text) {
charFreq[c]++; // Automatically creates entry if key doesn't exist
}
};

int main() {
// Unordered map with custom hash and equality functions
std::unordered_map < std::string, int, CustomHash, CustomEqual > myMap;
// Display character frequencies
std::cout << "Character frequencies in '" << text << "':" << std::endl;
for (const auto& pair : charFreq) {
std::cout << "'" << pair.first << "': " << pair.second << " times" << std::endl;
}

myMap["apple"] = 1;
// Find most frequent character
auto maxElement = std::max_element(charFreq.begin(), charFreq.end(),
[](const std::pair<char, int>& a, const std::pair<char, int>& b) {
return a.second < b.second;
});

// Will be treated as the same key as "apple"
myMap["APPLE"] = 2;
std::cout << "Most frequent character: '" << maxElement->first
<< "' appears " << maxElement->second << " times" << std::endl;

for (const auto & pair: myMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
}
return 0;
}
```

The above code snippet will return the following output:
The output of this code is:

```shell
apple: 2
Character frequencies in 'programming':
'i': 1 times
'm': 2 times
'n': 1 times
'a': 1 times
'g': 2 times
'o': 1 times
'r': 2 times
'p': 1 times
Most frequent character: 'm' appears 2 times
```

## Codebyte Example
> **Note:** The order of elements in an unordered_map is unspecified and may vary across executions.

This example demonstrates a practical use case where `unordered_map` efficiently counts character occurrences. The algorithm has O(n) time complexity, making it very efficient for frequency analysis tasks commonly used in text processing and data analysis.

## Codebyte Example: Building an Employee Database

This example shows how to use `unordered_map` to create a simple employee database system for quick employee information retrieval:

```codebyte/cpp
#include <iostream>
#include <unordered_map>
#include <string>

struct Employee {
std::string name;
std::string department;
double salary;

Employee() : name(""), department(""), salary(0.0) {} // Default constructor
Employee(const std::string& n, const std::string& dept, double sal)
: name(n), department(dept), salary(sal) {}
};


int main() {
// Create an unordered_map with default hash and equality functions
std::unordered_map<int, std::string> myMap;

// Insert elements into the unordered_map
myMap[1] = "one";
myMap[2] = "two";
myMap[3] = "three";

// Print the elements in the unordered_map
std::cout << "Elements in the unordered_map:" << std::endl;
for (const auto& pair : myMap) {
std::cout << pair.first << ": " << pair.second << std::endl;
// Create employee database using employee ID as key
std::unordered_map<int, Employee> employeeDB;

// Add employees to database
employeeDB.emplace(1001, Employee("Alice Johnson", "Engineering", 75000.0));
employeeDB.emplace(1002, Employee("Bob Smith", "Marketing", 65000.0));
employeeDB.emplace(1003, Employee("Carol Davis", "Engineering", 80000.0));
employeeDB.emplace(1004, Employee("David Wilson", "Sales", 60000.0));

// Function to search for employee
auto searchEmployee = [&](int id) {
auto it = employeeDB.find(id);
if (it != employeeDB.end()) {
const Employee& emp = it->second;
std::cout << "Employee Found:" << std::endl;
std::cout << "ID: " << id << std::endl;
std::cout << "Name: " << emp.name << std::endl;
std::cout << "Department: " << emp.department << std::endl;
std::cout << "Salary: $" << emp.salary << std::endl;
} else {
std::cout << "Employee with ID " << id << " not found." << std::endl;
}
return 0;
std::cout << std::endl;
};

// Search for specific employees
searchEmployee(1002); // Found
searchEmployee(1005); // Not found

// Update employee information
if (employeeDB.find(1001) != employeeDB.end()) {
employeeDB[1001].salary = 78000.0; // Give Alice a raise
std::cout << "Updated Alice's salary to $" << employeeDB[1001].salary << std::endl;
}

// Display all employees by department
std::cout << "\nEngineering Department Employees:" << std::endl;
for (const auto& pair : employeeDB) {
if (pair.second.department == "Engineering") {
std::cout << "ID: " << pair.first << ", Name: " << pair.second.name
<< ", Salary: $" << pair.second.salary << std::endl;
}
}

return 0;
}
```

This example demonstrates a real-world application where `unordered_map` serves as an efficient database for employee records. The constant-time lookup makes it ideal for systems that need to frequently access employee information by ID, such as payroll systems or HR applications.

## Frequently Asked Questions

### 1. What is the difference between `map` and `unordered_map`?

`map` maintains elements in sorted order using a balanced binary search tree (typically red-black tree), providing O(log n) operations, while `unordered_map` uses a hash table with O(1) average-case operations but no ordering guarantees.

### 2. When should I use `unordered_map` over `map`?

Use `unordered_map` when you need faster lookup times and don't require the elements to be in sorted order. It's ideal for scenarios like caching, frequency counting, and database indexing where performance is critical.

### 3. Can I use custom objects as keys in `unordered_map`?

Yes, but you need to provide a custom hash function and equality operator for your custom type. The hash function should be provided as a template parameter or through specialization of `std::hash`.