Rust lacks Enumerated::position() to get the current count

I want to know the current position without having to do weird syntax gymnastics

I don't know what you're talking about. If you're talking about iterators, every single one has an .enumerate() method.

5 Likes

They're likely talking about std::iter::Enumerate not having a method to get the current position.

@x4exr I can't see any reason not to have this. You could probably just open a github PR for it.

1 Like

The process is to open an ACP.

1 Like

You could get the current position from enumerate via peekable.

Or if the iterator is cheaply cloneable (such as iterating over a slice, or chars of a &str) you can also peek with iter.clone().next()

2 Likes

I'm not against exposing this information, but it's not entirely clear to me how the "position" of an Enumerated iterator would work.

For example, for a very simple enumeration of two elements, i would have these questions:

let mut it = "ab".chars().enumerate();
// 1: what's the position now? 0? or None because iteration hasn't started?
assert_eq!(it.next(), Some((0, 'a')));
// 2: and here? is it 0 because that's the first element, or 1 because we're past that?
assert_eq!(it.next(), Some((1, 'b')));
// 3: same question here
assert_eq!(it.next(), None);
// 4: and here? is the position 2, or None because the iterator is consumed?
assert_eq!(it.next(), None);
// 5: and now? if the position was 2 before, do we keep incrementing it with next()?

The previous answers that suggested using .peekable() or .clone().next() imply that the answers to those questions would be: Some(0), Some(1), None, None, None. If this is what you're looking for, then i'd agree with those suggestions. Using peekable() seems the most straightforward to me.

Another alternative could be adding an accessor method for the existing count field on the Enumerate struct. (The method couldn't be called position() because there's already a method called on Iterator, but i guess it could be called count()). If this approach was taken, then the answer to the questions above would be: 0, 1, 2, 2, 2. If this is what you're looking for, then yeah, exposing this would make sense i think.

@x4exr, do you have an example for where this method would be useful?

5 Likes

Prior art: CharIndices::offset() which was just recently stabilized after some back-and-forth about its utility and naming. To stay consistent, an equivalent Enumerate method should:

  • return the value that would be returned by the next next() call, except:
  • if next() would return None, return one-past-the-last.

So presumably this simply means returning the value of the count field.

9 Likes

Another alternative could be adding an accessor method for the existing count field on the Enumerate struct . (The method couldn't be called position() because there's already a method called on Iterator, but i guess it could be called count()). If this approach was taken, then the answer to the questions above would be: 0, 1, 2, 2, 2. If this is what you're looking for, then yeah, exposing this would make sense i think.

There is also an Iterator::count.

3 Likes

What kind of code do you have that you need this information?

Maybe there's a more idiomatic solution that doesn't need to access the counter separately.

8 Likes