Create an iterator from a single element - rust

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)?

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))

You can use the Option by-value iterator, into_iter:
Some(2).into_iter().chain((3..).step_by(2))

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

Related

std::iter::map rust run parallelly?

I have been searching to find parallelizes map in rust most answer point to rayon crate so I wonder if std::iter::map iterate sequentially by default?
I wonder if std::iter::map iterate sequentially by default?
It does
Rust iterators are lazy, meaning that nothing is computed unless asked explicitly. And they are computed one by one until the iterator is exhausted.
Map , from the documentation:
An iterator that maps the values of iter with f
Is an iterator adaptor, it will apply a transformation function on each item of the iterator one by one (when requested, through the next method).

Multiplying nested vec by scalar

I have a nested Vec<Vec<f64>> in Rust, and I want to multiply each f64 in place by a value DT. I am currently doing:
dcm_dot.iter_mut().map(|a| a.iter_mut().map(|b| * b * DT));
This works, however, I am getting a lazy iterator warning, that the .map()s must be consumed. Is there a more idiomatically correct way to do this?
Iterators in Rust are lazy so unless you use the result of the .map(),
the closure inside will not even be executed.
In order to ensure that your code actually changes the Vec, you should use .for_each() instead.
Playground

What is the difference between position() and rposition() for rust iterators and is there any reason for it?

So I was browsing through the iterator functions (because they are cool) and I noticed that there were two functions that seemed to do the exact same thing except one takes an ExactSizeIterator
and other doesn't.
What would be the use case of using one function over the other?
position starts at the beginning, and goes forward until it finds a matching element, and returns its position. This doesn't require knowing how many elements there are in total, hence Iterator is enough.
rposition starts at the end, and goes backward until it finds a matching element, and returns its position (from the beginning!). Because the position is returned from the beginning of the iterator (think of it as being usable as a slice index), it needs to know exactly how many elements there are in the iterator, hence ExactSizeIterator is required.

Efficiency of flattening and collecting slices

If one uses the standard .flatten().collect::<Box<[T]>>() on an Iterator<Item=&[T]> where T: Copy, does it:
perform a single allocation; and
use memcpy to copy each item to the destination
or does it do something less efficient?
Box<[T]> does not implement FromIterator<&T>, so I'll assume your actual inner iterator is something that yields owned Ts.
FromIterator<T> for Box<[T]> forwards to Vec<T>, which uses size_hint() to reserve space for lower + 1 items, and reallocates as it grows beyond that (moving elements as necessary). So the question is, what does Flatten<I> return for size_hint?
The implementation of Iterator::size_hint for Flatten<I> forwards to the internal struct FlattenCompat<I>, which is a little complicated because it supports double-ended iteration, but ultimately returns (0, None) if the outer iterator has not been advanced or exhausted.
So the answer to your question is: it does something less efficient. Namely, (unless you have already called next or next_back on the iterator at least once) it creates an empty Vec<T> and grows it progressively according to whatever growth strategy Vec uses (which is unspecified, but guaranteed by the documentation to result in O(1) amortized push).
This isn't an artificial limitation; it is fundamental to the way Flatten works. The only way you could pre-calculate the size of the flattened iterator is by exhausting the outer iterator and adding up all the inner size_hints. This is a bad idea both because it doesn't always work (the inner iterators may not return useful size_hints) and because you also have to find a way to keep the inner iterators around after exhausting the outer one; there's no solution that would be acceptable for a general purpose iterator adapter.
If you know something about your particular iterator that enables you to know what the final size should be, you can reserve the allocation yourself by calling Vec::with_capacity and use Extend to fill it from the flattened iterator, rather than using collect.

Groovy iterate over Map

I am having a groovy map which holds this kinda values
Map testMap = [1:[1,1,1],2:[2,2,2]]
Here when I call collect function like this
testMap.collect {it.value}
I getting the output like
[[1, 1, 1], [2, 2, 2]]
But I want the output as [1,1,1,2,2,2]
is their any groovy method to achieve this, without using each method
You can use groovy's flatten() method.
testMap.collect {it.value}.flatten()
There is even simplier solution
[1:[1,1,1],2:[2,2,2]].collectMany{it.value}
A couple of the solutions here use the collect family, which is ok if you're doing mutations on the data, but in this case it's just grabbing all the values which would be better served using the spread operator on the values of the map
testMap*.value.flatten()
or with functions on the map
testMap.values().flatten()
Note it's value when spreading over each element of the map, and values() when asking the map directly in one go for the entries values.
Both of these read more as "getting values out of testMap" rather than collect which is usually used for mutations on the map.
It's a matter of style, but if you only use collect when you're going to mutate the data, you'll have more readable code.

Resources