BooleanCat / go-functional

go-functional is a library of iterators to augment the standard library
MIT License
405 stars 23 forks source link

[Feature 🔨]: Unzip iterator that produces `iter.Seq[V], iter.Seq[W]` from `iter.Seq2[V, W]` #131

Closed BooleanCat closed 1 month ago

BooleanCat commented 1 month ago

Is your feature request related to a problem? Please describe.

The inverse of this operation already exists in it.Zip. This operation may be helpful for situations where you either wish to iterate over items at different speeds (and can accept the memory cost) or where you wish to apply functions to iter.Seqs that support iter.Seq rather than the Seq2 kind.

Describe the solution you'd like

keys, values := it.Unzip(maps.All(map[int]string{1: "one", 2: "two"}))
fmt.Println(it.Collect(keys))
fmt.Println(it.Collect(values))

Does this incur a breaking change?

No.

Do you intend to build this feature yourself?

Yes.

Additional context

This is actually trickier than it sounds and I already had one aborted attempt at this, some things to consider:

  1. Since the two iterators created by it.Unzip may consume items from the original at different speeds, unyielded but consumed values need to be stored incurring a memory cost.
  2. In order to avoid deadlocking, the storage of the unyielded values needs to be infinite to avoid deadlocking.
  3. The solution needs to be thread-safe between the two iterators returns by this to support concurrent iteration.