本页尚未翻译,因此以英文显示。 参与翻译

zip3

Three iterables walked side by side — zip with one more input.

Iterable<(A, B, C)> zip3<A, B, C>(Iterable<A> iterable1, Iterable<B> iterable2, Iterable<C> iterable3) FxAsyncIterable<(A, B, C)> zip3Async<A, B, C>(FxAsyncIterable<A> iterable1, FxAsyncIterable<B> iterable2, FxAsyncIterable<C> iterable3)

Lecture

zip3 is zip with a third iterable. Everything the zip page explains holds unchanged — one record per step, laziness, and stopping the moment any input runs out, so the result is as long as the shortest of the three. The element type is a Dart record (A, B, C), so destructure it by pattern matching rather than by index.

It exists as its own function because Dart has no variadic generics: a single zip taking a list of iterables would have to erase the per-input types, and (A, B, C) is exactly what makes the result worth having. The same reason tee is joined by tee3.

One asymmetry to know: zip has a chain method (fx(a).zip(b)) and zip3 does not — a chain has one receiver and zip3 needs three peers. Call it as a top-level function and wrap the result in fx() to carry on, as the demo's last line does. zip3Async is the async form, and like zipAsync it issues all three next() calls before awaiting any of them, so the sources are pulled in parallel per record rather than one after another.

Demo · Three inputs, one record per step

Related: zip — the two-iterable form, and the full explanation · zipWith — combine instead of pairing · transpose — any number of iterables, at the cost of a shared element type