Skip to content

Hashmaps explained #4

Description

@voroskoi

Hi,

Thank You very much for this article, this is very useful information and they answer valid questions for those who just started learning zig.

I think it would be good to talk about iterating over the elements and possibly removing some of them which can be quite tricky. (At least was not obvious for me.)

I golang You can do the following:

myMap := map[Point]struct{}{}

for item := range m.paper {
  if some_condition {
      delete(myMap, item)
    }
}

This will remove the item from the map.

However with zig You probably want to use std.AutoArrayHashMap to make iteration over the items fast as the documentation suggests. (Can You explain why is that? Sadly I do not :-( )

const Dots = std.AutoArrayHashMap(Point, void);
var my_dots = Dots.init(allocator);
defer my_dots.deinit();

var to_remove = std.ArrayList(Point).init(allocator);
defer to_remove.deinit();

for (my_dots.keys()) |item| {
    if (item[0] > value) {
        try to_remove.append(item); // if You try to remove in place the for cycle will run out of bounds!
    }
}

for (to_remove.items) |item| {
    _ = my_dots.swapRemove(item);
}

If the ordering of the items also matter for You, then to remove them You have to sort the indexes first, and then loop over them backwards, so swapRemove() will not ruin the order (or have to use orderedRemove() which is O(n).

std.sort.sort(usize, to_remove.items, {}, comptime std.sort.desc(usize));
for (to_remove.items) |idx| {
    _ = my_dots.swapRemove(idx);
}

Sometimes You do not want to collect the items to remove, just the indexes, because You are removing items from an std.ArrayList for example. When You write You first reverse loop in zig You will be surprised of the out-of-bound errors. Here is the zig way of writing the reverse loop:

var i: usize = to_remove.items.len;
while (i > 0) : (i -= 1) {
    self.dots.swapRemove(idx-1)
}

I find it quite unusual that it starts with items.len, runs til i>0 and uses i-1 as the index.

Let me know if I am doing this wrong, I would love to know a simpler solution for these problems.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions