Michael
Michael

Reputation: 2942

Detect last item of an Iterator

My code analyzes log files line by line. The last line typically is an empty ("") line and should be ignored completely. But how can I detect the last line in my loop?
The iterator doesn't know how long it is and collecting all items to an array is inefficient and might fill up memory too much.

let file = File::open(&files[index])
    .map_err(|e| format!("Could not open log file: {}", e))?;
let reader = BufReader::new(file);
for (index, line) in reader.lines().enumerate() {
    let line = line.unwrap();
    if is_last_line() && line == "" {
        break;
    }
    // do something with the line...
}

is_last_line() doesn't exist. How to detect the last line?

Upvotes: 4

Views: 2126

Answers (2)

hellow
hellow

Reputation: 13410

You could use the Itertools::with_position function:

use itertools::{Itertools, Position};

let file = File::open(&files[index]).map_err(|e| format!("Could not open log file: {}", e))?;
let reader = BufReader::new(file);

for line in reader.lines().enumerate().with_position() {
    match line {
        Position::Last((idx, _)) => println!("line {} is the last line!", idx),
        Position::First((idx, text)) | Position::Middle((idx, text)) => (),
        Position::Only((idx, _)) => println!("there is only one line in your file"),
    }
}

Upvotes: 8

Masklinn
Masklinn

Reputation: 42197

You can use the peekable adapter.

This requires switching to manual iteration (a while let loop and explicitly calling next), but it lets you peek() the iterator to see if there is a next item. If there isn't, you know it's the last line (at least for the more fusable iterators).

let file = File::open(&files[index])
    .map_err(|e| format!("Could not open log file: {}", e))?;
let reader = BufReader::new(file);
let mut iterator = reader.lines().enumerate().peekable();
while let Some((index, line)) = iterator.next() {
    if line == "" && iterator.peek().is_none() {
        break;
    }
    // do something with the line...
}

Upvotes: 5

Related Questions