How to check whether this is the last item in an iterator?

I am concatenating several items in vec, manually into string for viewing, like [a, b, c].

let iter = vec.iter(); // vec is &Vec, not mutable
let mut str = String::new();
str.push_str("[");
while let Some(v) = iter.next() {
  str.push_str(&v.str());
  str.push_str(", ");
}
str.push_str("]");

So I got [a, b, c, ]. It is troublesome to detect the length and to remove the ending comma. Is there any easy way for this?

You could use a Peekable iterator to check whether there is another element remaining or not.

2 Likes

ยทยทยท
if matches!(iter.peek(), Some(_)) {
str.push_str(", ");
}
ยทยทยท
It seems well, thanks for your patience!

2 Likes

While your actual question has been answered, note that in your example, if you treat the first (rather than last) item as special, you can make the whole thing more efficient by avoiding the check alltoghether.

    let mut iter = vec.iter();
    let mut str = String::new();
    str.push('[');
    if let Some(first) = iter.next() {
        str.push_str(first);
    }
    while let Some(next) = iter.next() {
        str.push_str(", ");
        str.push_str(next)
    }
    str.push(']');
    str

Also, there is a slice::split_first method that may make things even nicer (depending on taste and situation). Here's a playground with two ways to do it.

7 Likes

That's such a nice mind, I think this cost less and seems more beautifully. Thanks for your addition!

If you just need to check for Some/None rather than match a more complex pattern, the is_some()/is_none() methods come in handy.

1 Like

@Subkey Just in case you didn't know, this exact functionality is implemented in itertools: Itertools in itertools - Rust

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.