Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Zig Dictionary
  3. ArrayList / HashMap

ArrayList / HashMap

Zig's standard library provides ArrayList for dynamic arrays and HashMap (and AutoHashMap) for hash maps. Both take an allocator during initialization, making memory allocation and deallocation responsibilities explicit. ArrayList automatically expands its internal buffer as elements are added, and HashMap stores key-value pairs with O(1) average time complexity.

Syntax

// -----------------------------------------------
// ArrayList — dynamic array
// -----------------------------------------------

// Initialize (pass an allocator)
var list = std.ArrayList(ElementType).init(allocator);
defer list.deinit();  // frees the internal buffer when the scope exits

// Append to the end
try list.append(value);

// Insert at a specific position (index, value)
try list.insert(index, value);

// Remove an element (by index, preserves order)
_ = list.orderedRemove(index);

// Remove an element (by index, swaps with last element — faster)
_ = list.swapRemove(index);

// Check length and capacity
list.items.len   // current number of elements
list.capacity    // internal buffer capacity

// Access as a slice
for (list.items) |item| { /* … */ }

// -----------------------------------------------
// AutoHashMap — hash map with automatic hash function
// -----------------------------------------------

// Initialize (pass key type, value type, and allocator)
var map = std.AutoHashMap(KeyType, ValueType).init(allocator);
defer map.deinit();  // frees the internal table when the scope exits

// Add or update an entry
try map.put(key, value);

// Get an entry (returns null if not found)
const val = map.get(key);  // ?ValueType

// Remove an entry
_ = map.remove(key);       // returns bool indicating whether deletion succeeded

// Check if a key exists
const exists = map.contains(key);  // bool

// Iterate over all entries
var it = map.iterator();
while (it.next()) |entry| {
    _ = entry.key_ptr.*;    // key
    _ = entry.value_ptr.*;  // value
}

// -----------------------------------------------
// StringHashMap — hash map with string keys
// -----------------------------------------------

var smap = std.StringHashMap(ValueType).init(allocator);
defer smap.deinit();

try smap.put("key_string", value);

Method Reference

Method / PropertyTargetDescription
init(allocator)ArrayList / HashMapInitializes the collection with an allocator.
deinit()ArrayList / HashMapFrees the internal buffer or table. Typically used with defer.
append(value)ArrayListAppends an element to the end. Automatically expands capacity if needed.
insert(index, value)ArrayListInserts an element at the specified index. Shifts subsequent elements backward.
orderedRemove(index)ArrayListRemoves an element while preserving order. Takes O(n) time.
swapRemove(index)ArrayListSwaps the element with the last element, then removes it. O(1) but does not preserve order.
itemsArrayListThe internal slice ([]T). Use this for for loops and index access.
put(key, value)HashMapAdds or overwrites a key-value pair.
get(key)HashMapReturns the value for the key as ?T. Returns null if the key does not exist.
remove(key)HashMapRemoves the entry and returns a bool indicating whether deletion succeeded.
contains(key)HashMapReturns a bool indicating whether the key exists.
count()HashMapReturns the number of registered entries.
iterator()HashMapReturns an iterator for traversing all entries.
getOrPut(key)HashMapReserves an entry if the key does not exist. The result provides .found_existing and .value_ptr.

Sample Code

collection.zig
// collection.zig — basic example of ArrayList and HashMap
// Demonstrates dynamic array operations with ArrayList
// and key-value management with AutoHashMap / StringHashMap

const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();

    // Use GeneralPurposeAllocator
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // -----------------------------------------------
    // ArrayList — dynamic list of names
    // -----------------------------------------------

    try stdout.print("=== Member List (ArrayList) ===\n\n", .{});

    // Initialize an ArrayList of []const u8
    var members = std.ArrayList([]const u8).init(allocator);
    defer members.deinit();

    // Add members
    try members.append("user1");
    try members.append("user2");
    try members.append("user3");
    try members.append("user4");
    try members.append("user5");

    try stdout.print("Count: {d}\n", .{members.items.len});
    try stdout.print("All members:\n", .{});
    for (members.items, 0..) |name, i| {
        try stdout.print("  [{d}] {s}\n", .{ i, name });
    }

    // Insert a new member at the beginning (index 0)
    try members.insert(0, "user0");
    try stdout.print("\nAfter inserting user0 at the beginning:\n", .{});
    for (members.items, 0..) |name, i| {
        try stdout.print("  [{d}] {s}\n", .{ i, name });
    }

    // Remove the element at index 2, preserving order
    const removed = members.orderedRemove(2);
    try stdout.print("\nAfter removing index 2 ({s}):\n", .{removed});
    for (members.items, 0..) |name, i| {
        try stdout.print("  [{d}] {s}\n", .{ i, name });
    }

    // -----------------------------------------------
    // AutoHashMap — item grade management
    // Key: u8 (ID), Value: struct
    // -----------------------------------------------

    try stdout.print("\n=== Item Grade Table (AutoHashMap) ===\n\n", .{});

    // Struct holding item information
    const Item = struct {
        name:  []const u8,  // name
        grade: []const u8,  // grade
        power: u32,          // power level (arbitrary unit)
    };

    // Key: u8 (ID), Value: Item
    var grade_map = std.AutoHashMap(u8, Item).init(allocator);
    defer grade_map.deinit();

    // Add entries
    try grade_map.put(1, .{ .name = "item_s1",  .grade = "S", .power = 9999 });
    try grade_map.put(2, .{ .name = "item_s2",  .grade = "S", .power = 9500 });
    try grade_map.put(3, .{ .name = "item_s3",  .grade = "S", .power = 9200 });
    try grade_map.put(4, .{ .name = "item_a1",  .grade = "A", .power = 7000 });
    try grade_map.put(5, .{ .name = "item_a2",  .grade = "A", .power = 6500 });

    try stdout.print("Count: {d}\n\n", .{grade_map.count()});

    // Retrieve by ID (get returns ?Item)
    const target_id: u8 = 4;
    if (grade_map.get(target_id)) |s| {
        try stdout.print("Item with ID {d}:\n", .{target_id});
        try stdout.print("  Name : {s}\n", .{s.name});
        try stdout.print("  Grade: {s}\n", .{s.grade});
        try stdout.print("  Power: {d}\n", .{s.power});
    }

    // Look up a non-existent ID
    const missing_id: u8 = 99;
    const missing = grade_map.get(missing_id);
    try stdout.print("\nSearch result for ID {d}: {?}\n", .{ missing_id, missing });

    // Traverse all entries with an iterator
    try stdout.print("\n--- All items ---\n", .{});
    var it = grade_map.iterator();
    while (it.next()) |entry| {
        const id = entry.key_ptr.*;
        const s  = entry.value_ptr.*;
        try stdout.print("  ID {d}: {s} ({s}) power {d}\n", .{ id, s.name, s.grade, s.power });
    }

    // Remove an entry
    _ = grade_map.remove(2);
    try stdout.print("\nCount after removing ID 2: {d}\n", .{grade_map.count()});

    // -----------------------------------------------
    // StringHashMap — keyword frequency count
    // Key: string, Value: u32 (occurrence count)
    // -----------------------------------------------

    try stdout.print("\n=== Keyword Count (StringHashMap) ===\n\n", .{});

    var term_count = std.StringHashMap(u32).init(allocator);
    defer term_count.deinit();

    // Keyword list
    const terms = [_][]const u8{
        "attack",  "critical",  "attack",
        "defense", "critical",  "item_x",
        "attack",  "item_x",    "defense",
        "critical",
    };

    // Increment counts using getOrPut
    for (terms) |term| {
        // If the key does not exist, value_ptr is set to 0
        const result = try term_count.getOrPut(term);
        if (!result.found_existing) {
            result.value_ptr.* = 0;  // initialize to 0 on first occurrence
        }
        result.value_ptr.* += 1;  // increment count
    }

    try stdout.print("Keyword occurrences:\n", .{});
    var term_it = term_count.iterator();
    while (term_it.next()) |entry| {
        try stdout.print("  {s}: {d}\n", .{ entry.key_ptr.*, entry.value_ptr.* });
    }
}
zig run collection.zig
=== Member List (ArrayList) ===

Count: 5
All members:
  [0] user1
  [1] user2
  [2] user3
  [3] user4
  [4] user5

After inserting user0 at the beginning:
  [0] user0
  [1] user1
  [2] user2
  [3] user3
  [4] user4
  [5] user5

After removing index 2 (user2):
  [0] user0
  [1] user1
  [2] user3
  [3] user4
  [4] user5

=== Item Grade Table (AutoHashMap) ===

Count: 5

Item with ID 4:
  Name : item_a1
  Grade: A
  Power: 7000

Search result for ID 99: null

--- All items ---
  ID 1: item_s1 (S) power 9999
  ID 2: item_s2 (S) power 9500
  ID 3: item_s3 (S) power 9200
  ID 4: item_a1 (A) power 7000
  ID 5: item_a2 (A) power 6500

Count after removing ID 2: 4

=== Keyword Count (StringHashMap) ===

Keyword occurrences:
  attack: 3
  critical: 3
  defense: 2
  item_x: 2

Notes

Zig's ArrayList is the equivalent of C++'s std::vector or Rust's Vec — a dynamic array that you access through its .items slice just like a regular array. For removing elements, you have two options: orderedRemove (preserves order, O(n)) and swapRemove (changes order, O(1)). For HashMap, Zig provides AutoHashMap for types supported by std.hash_map.AutoContext (such as integers and structs), and StringHashMap for string keys. getOrPut reserves a new entry if the key does not exist and lets you check whether the entry already existed via the found_existing flag — this allows you to handle both initialization and incrementing in a single call. For both collections, registering deinit() with defer is the standard pattern. For more on allocators, see Allocator Basics.

If you find any errors or copyright issues, please .