HashMap

std.HashMap implements a general-purpose hash table. To use it, we have to provide a context that implements the hash function we want to use.

const std = @import("std");
const print = std.debug.print;

// Let’s say we have a User type that we want to use for
// the keys in a map. We can’t use it with AutoHashMap
// because it contains a slice.
const User = struct {
    id: u64,
    name: []const u8,

    fn init(id: u64, name: []const u8) User {
        return .{ .id = id, .name = name };
    }
};

// First, we need to define a context type with methods
// for equality and hashing.
const Context = struct {
    pub fn eql(_: Context, u: User, v: User) bool {
        return u.id == v.id;
    }

    // We’ll rely on the standard library’s hash
    // function for integers.
    pub fn hash(_: Context, u: User) u64 {
        return std.hash.int(u.id);
    }
};

pub fn main(init: std.process.Init) !void {
    const allocator = init.gpa;

    // The “max load percentage” determines when the map
    // re-allocates memory as it fills up.
    var admins = std.HashMap(
        User, // key type
        void, // value type
        Context, // hash context
        80, // max load percentage
    ).init(allocator);
    defer admins.deinit();

    try admins.put(User.init(1, "olivia"), {});
    try admins.put(User.init(5, "freya"), {});

    print("Admin users:\n", .{});
    var iterator = admins.iterator();
    while (iterator.next()) |entry| {
        const user = entry.key_ptr.*;
        print("{} {s}\n", .{ user.id, user.name });
    }
}
$ zig run hashmap.zig
Admin users:
5 freya
1 olivia

This example just shows the basics. For more, see AutoHashMap, which has the same functionality but for different key types.

Next example: Sorting.