#can we not iterate two iterators together in the while syntax?

1 messages · Page 1 of 1 (latest)

crimson valley
#

I'm trying to do this

while (my_path_it.next(), path_it.next()) |my_path_part, path_part| {

To compare the prefixes of two paths segment by segment, getting the iterators with

std.mem.split(u8, path, "/")

I know you can loop over two things in some ways. Does it depend on for vs while, arrays vs iterators, both?

cursive oasis
#

just do

while (true) {
    const my_path_part = my_path_it.next() orelse break;
    const path_part = path_it.next() orelse break;
}

if thats what you want

crimson valley
#

yep that's where i thought i'd head next. thanks!

amber sage
cursive oasis
#

with iterators, if you discard an item, that’s gone unless you re-iterate the entire thing again

#

and you cant even do that sometimes

amber sage
cursive oasis
#

I really dont see that

amber sage
#

Well, you can discard the item you are currently iterating over, which would break your next() call (depending on the iterator implementation).

#

And this situation is not contrived, actually it's somewhat common.

cursive oasis
#

actually looking at the langauge reference, all arrays/slices you iterate over in for loops must be the same length as eachother (and that’s checked at compile time and runtime)

amber sage
cursive oasis
#

that obviously cant be checked for iterators though

amber sage
cursive oasis
#

that would be very late
it’s defined as UB but won’t be checked unless the entire iteration completes
so if you have an early exit every time, that would be still be UB but it would never be caught

amber sage
#

Fair point, but then I'm not 100% sure it's really a problem. Anyway, not too important.

buoyant thicket
#

by discarding the capture, all you're discarding is the result of slice[i], which you can even easily recover

#

and unlike while iteration, it can be checked ahead of time, meaning there actually can't be a failure during iteration from the loop itself

#

the only slim circumstance in which you would fail would be a segmentation fault if you were to iterate out of bounds across a page boundary

crimson valley
cursive oasis
#

you can't check if an iterator is the same length as another

#

well you can, but zig can't do that for you

crimson valley
#

ah true

buoyant thicket
#

an iterator is not a bespoke interface of the language or anything

#

an iterating function needn't even be called next

#

and like I said, it could be any arbitrarily complex calculation

#

many iterators are more generators than they are purely iterators over data

crimson valley
#

yes, i'm still soaking some of these details in

tall tree
crimson valley
#

yep i've got a couple of working versions now. haven't put this one through its paces yet but i think it's good

fn splittyStartsWith(haystack: *std.mem.SplitIterator(u8, .scalar), needle: *std.mem.SplitIterator(u8, .scalar)) bool {
    while (haystack.next()) |haystack_item| {
        if (needle.next()) |needle_item| {
            if (!std.mem.eql(u8, haystack_item, needle_item)) {
                return false;
            }
        } else {
            return false;
        }
    }
    return true;
}
#

ah no it's not. needs some tweaks

#

i did a version where i convert the SplitIterators to arrays of slices that's working but i'm gonna try to finish the above one too

tall tree
#

that's not what I meant

#

why can't you just std.mem.startsWith(u8, "/some/path/here/", thing)?

crimson valley
#

because of how the code around it works. i have to split the paths anyway. but yeah i'm experimenting with a version with std.mem.startsWtih too now that i have a known working version

native tinsel
#

If you want one to remain going and keep the other as null then you're going to have to implement it yourself

amber sage