How it works...
Rust's iterators are heavily inspired by functional programming languages, which makes them very handy to use. As an iterator, every operation is applied sequentially one element at a time, but only as far as the iterator is moved forward. There are several types of operations shown in this recipe. The most important ones are as follows:
- map() operations execute a value or type transformation, and they are very common and easy to use.
- filter(), in the same way as many similar operations, executes a predicate (a function with a Boolean return value) in order to determine whether an element is to be included in the output. Examples are find(), take_while(), skip_while(), and any().
- Aggregation functions such as fold(), sum(), min(), and max() are used to reduce the entire iterator's contents into a single object. That could be a number (sum()) or a hash map (for example, by using fold()).
- chain(), zip(), fuse(), and many more combine iterators so that they can be iterated over in a single loop. Typically, we use these if multiple run-throughs are otherwise required.
This more functional style of programming not only reduces the amount of code that has to be written, but also acts as a universal vocabulary: instead of reading through the entire for loop that pushes items into a previously defined list if a condition applies, a function call to filter() tells the reader what to expect. Steps 2 and 3 show different function invocations to transform (Step 2) or filter (Step 3) collections based on various use cases.
Additionally, iterators can be chained together, so a call to iterator.filter().map().fold() is not unusual and typically quicker to reason about than a loop that does the same thing. As the last step, most iterators are collected into their target collection or variable type. collect() evaluates the entire chain, which means that its execution is costly. Since the entire topic is very specific to the tasks at hand, check out the code we wrote and the outcomes/invocations to get the most out of it. Step 4 only shows running the tests, but the real story is inside the code.
Done! We've successfully learned how to filter and transform sequences efficiently. Move on to the next recipe to learn more!