Skip to content
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

Hashmaps explained #4

Open
voroskoi opened this issue Mar 29, 2022 · 0 comments
Open

Hashmaps explained #4

voroskoi opened this issue Mar 29, 2022 · 0 comments

Comments

@voroskoi
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant