20

I would like to prepend an element to an iterator. Specifically, I would like to create an iterator that steps through the sequence [2, 3, 5, 7, 9, ...] up to some maximum. The best I've been able to come up with is

range_step_inclusive(2,2,1).chain(range_step_inclusive(3, max, 2))

But the first iterator is kind of a hack to get the single element 2 as an iterator. Is there a more idiomatic way of creating a single-element iterator (or of prepending an element to an iterator)?

awelkie
  • 2,422
  • 1
  • 22
  • 32

3 Answers3

27

This is the exact use case of std::iter::once.

Creates an iterator that yields an element exactly once.

This is commonly used to adapt a single value into a chain of other kinds of iteration. Maybe you have an iterator that covers almost everything, but you need an extra special case. Maybe you have a function which works on iterators, but you only need to process one value.

range_step_inclusive is long gone, so let's also use the inclusive range syntax (..=):

iter::once(2).chain((3..=max).step_by(2))
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
CAD97
  • 1,160
  • 12
  • 29
7

You can use the Option by-value iterator, into_iter:

Some(2).into_iter().chain((3..).step_by(2))
Community
  • 1
  • 1
huon
  • 94,605
  • 21
  • 231
  • 225
5

It is not less boilerplate, but I guess it is more clear:

Repeat::new(2i).take(1).chain(range_step_inclusive(3, max, 2))

Repeat::new will create an endless iterator from the value you provide. Take will yield just the first value of that iterator. The rest is nothing new.

You can run this example on the playpen following the link: http://is.gd/CZbxD3

aochagavia
  • 5,887
  • 5
  • 34
  • 53