2

I have a function that takes array of posts and an optional after_id to skip posts with an id less or equal to given.

fn get_page<'a>(data: &'a Vec<u64>, after_id: Option<u64>) -> Vec<&u64> {
    let data = data.iter();
    let data = match after_id {
        Some(id) => data.skip_while(|&&post| post <= id),
        None => data,
    };

    data.take(10).collect()
}

This code triggers a compilation error, stating that Some arm creates a iter::SkipWhile struct and its type is incompatible with posts type (slice::Iter) from None arm.

The only fix I see, without deconstructing match into ifs or something like that, is:

let posts = match after_id {
    Some(id) => posts.skip_while(|post| post.id <= id).collect(),
    None => posts.collect(),
};

The obvious downside is that I needlessly iterate whole collection and use extra memory.

Is it possible to apply skip_while conditionally and store the result in a single variable, without collecting an intermediate result?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
utter_step
  • 633
  • 7
  • 14
  • 1
    See also [Why is it discouraged to accept a reference to a String (&String), Vec (&Vec) or Box (&Box) as a function argument?](https://stackoverflow.com/q/40006219/155423). – Shepmaster May 06 '18 at 20:26
  • I believe your question is already answered by the answers of [Iterate over one of several possible iterators](https://stackoverflow.com/q/29760668/155423). If you disagree, please [edit] your question to explain the differences. Otherwise we can mark this as answered. – Shepmaster May 06 '18 at 20:31
  • 2
    @Shepmaster thanks for your comments and edits! Seems like the answer you provided is exactly what I'm looking for, so I'm marking this answered :) – utter_step May 06 '18 at 20:46

0 Answers0