Skip to main content
Version: Zig 0.13.0

Hash Maps

The standard library provides std.AutoHashMap, which lets you easily create a hash map type from a key type and a value type. These must be initiated with an allocator.

Let's put some values in a hash map.

test "hashing" {
const Point = struct { x: i32, y: i32 };

var map = std.AutoHashMap(u32, Point).init(
test_allocator,
);
defer map.deinit();

try map.put(1525, .{ .x = 1, .y = -4 });
try map.put(1550, .{ .x = 2, .y = -3 });
try map.put(1575, .{ .x = 3, .y = -2 });
try map.put(1600, .{ .x = 4, .y = -1 });

try expect(map.count() == 4);

var sum = Point{ .x = 0, .y = 0 };
var iterator = map.iterator();

while (iterator.next()) |entry| {
sum.x += entry.value_ptr.x;
sum.y += entry.value_ptr.y;
}

try expect(sum.x == 10);
try expect(sum.y == -10);
}

.fetchPut puts a value in the hash map, returning a value if there was previously a value for that key.

test "fetchPut" {
var map = std.AutoHashMap(u8, f32).init(
test_allocator,
);
defer map.deinit();

try map.put(255, 10);
const old = try map.fetchPut(255, 100);

try expect(old.?.value == 10);
try expect(map.get(255).? == 100);
}

std.StringHashMap is also provided for when you need strings as keys.

test "string hashmap" {
var map = std.StringHashMap(enum { cool, uncool }).init(
test_allocator,
);
defer map.deinit();

try map.put("loris", .uncool);
try map.put("me", .cool);

try expect(map.get("me").? == .cool);
try expect(map.get("loris").? == .uncool);
}

std.StringHashMap and std.AutoHashMap are just wrappers for std.HashMap. If these two do not fulfil your needs, using std.HashMap directly gives you much more control.

If having your elements backed by an array is wanted behaviour, try std.ArrayHashMap and its wrapper std.AutoArrayHashMap.