WEBVTT

00:00:00.700 --> 00:00:04.945
Our task is to select active users and return their names.

00:00:05.095 --> 00:00:10.002
A list holds the source records, and a stream describes how to process them.

00:00:10.152 --> 00:00:14.355
We will filter, transform, limit, and finally collect results.

00:00:14.505 --> 00:00:20.371
The important idea is that building a stream pipeline and consuming it are different moments.

00:00:20.521 --> 00:00:27.988
We will make that visible with a diagnostic step, then discuss why a stream should be treated as a single

00:00:27.988 --> 00:00:28.735
use computation.

00:00:30.880 --> 00:00:33.845
Stream converts the list into a lazy source.

00:00:33.995 --> 00:00:36.939
Where retains records whose active field is true.

00:00:37.089 --> 00:00:43.575
Map turns each retained record into its name, so the element type changes from a map to a string.

00:00:43.725 --> 00:00:46.285
Take caps the number of resulting names.

00:00:46.435 --> 00:00:52.557
At this point we have described the work; we have not yet requested the complete list of answers.

00:00:52.707 --> 00:00:58.211
Keep the source list if you expect to build another independent computation later.

00:01:00.360 --> 00:01:03.709
Collect is the terminal operation in this example.

00:01:03.859 --> 00:01:08.105
It requests the stream elements and materializes them in a list.

00:01:08.255 --> 00:01:12.884
The output contains Ada and Grace because Linus failed the predicate.

00:01:13.034 --> 00:01:17.365
We can print names again because it is now a reusable list.

00:01:17.515 --> 00:01:21.589
That convenience has a cost: collection stores the results.

00:01:21.739 --> 00:01:29.496
For large or unbounded input, decide whether you really need a complete list or should process a bounded

00:01:29.496 --> 00:01:30.358
amount instead.

00:01:32.510 --> 00:01:37.545
Inspect provides a visible diagnostic without changing each element.

00:01:37.695 --> 00:01:44.853
Run this file and watch the ordering: before collect appears first, then the inspected numbers, then the

00:01:44.853 --> 00:01:45.695
collected list.

00:01:45.845 --> 00:01:49.962
Creating the pipeline did not eagerly print every source item.

00:01:50.112 --> 00:01:52.757
The consumer pulled the work through the stages.

00:01:52.907 --> 00:02:00.001
Use this technique while learning, but keep production transformations focused on data and remove noisy

00:02:00.001 --> 00:02:04.257
diagnostics when they no longer help explain the behavior.

00:02:06.410 --> 00:02:10.250
Filtering before take asks for the first two matching values.

00:02:10.400 --> 00:02:16.898
Taking two before filtering would only inspect the first two source values, which do not match this

00:02:16.898 --> 00:02:19.573
predicate, so the result would be empty.

00:02:19.723 --> 00:02:23.841
Both pipelines are meaningful, but they answer different questions.

00:02:23.991 --> 00:02:28.428
State your question in ordinary language before choosing the order.

00:02:28.578 --> 00:02:36.153
A limit usually describes either how much source input to inspect or how many accepted results to keep;

00:02:36.153 --> 00:02:37.837
those are different boundaries.

00:02:39.990 --> 00:02:44.875
Flat map is useful when each input element produces a smaller stream.

00:02:45.025 --> 00:02:50.124
Here each batch is a list, so the closure converts that batch into a stream.

00:02:50.274 --> 00:02:57.465
Flat map concatenates those child streams lazily, and collect produces one list containing one, two,

00:02:57.465 --> 00:02:58.423
three, four.

00:02:58.573 --> 00:03:03.821
Ordinary map would keep one result per batch instead of flattening their elements.

00:03:03.971 --> 00:03:11.708
Notice the explicit stream conversion inside the closure: the operator expects a child stream, not an

00:03:11.708 --> 00:03:12.675
arbitrary list.

00:03:14.830 --> 00:03:17.006
Treat a stream as single use.

00:03:17.156 --> 00:03:23.620
When you need to repeat a computation, build a fresh stream from the reusable source, as shown here.

00:03:23.770 --> 00:03:29.573
Alternatively, collect once and reuse the resulting list if the result is small enough.

00:03:29.723 --> 00:03:35.141
Do not rely on a second terminal operation to replay the original source.

00:03:35.291 --> 00:03:42.258
The exact diagnostic for a consumed stream may depend on the operator, so make ownership and consumption

00:03:42.258 --> 00:03:45.126
clear in the structure of your script.

00:03:47.280 --> 00:03:49.520
Collect needs the stream to finish.

00:03:49.670 --> 00:03:56.184
Later, file watchers and timer sources may continue indefinitely, so collecting them without a bound is

00:03:56.184 --> 00:03:59.441
not a way to obtain a quick sample.

00:03:59.591 --> 00:04:06.779
This finite range example shows the intended pattern safely: add a meaningful limit before

00:04:06.779 --> 00:04:07.292
materialization.

00:04:07.442 --> 00:04:11.218
Take also closes upstream early after reaching its count.

00:04:11.368 --> 00:04:17.363
Choose the bound from the task rather than copying an arbitrary number into every pipeline.

00:04:19.510 --> 00:04:24.694
For practice, add another active record and increase the result limit to three.

00:04:24.844 --> 00:04:27.724
Predict the names, run the script, and compare.

00:04:27.874 --> 00:04:35.061
Then move take before where and explain any difference using the distinction between source items and

00:04:35.061 --> 00:04:35.959
accepted results.

00:04:36.109 --> 00:04:41.891
You can now construct a source, transform it lazily, and choose when to consume it.

00:04:42.041 --> 00:04:48.718
Next we will apply these habits to paths and files, where the data comes from your own working directory.

