Skip to content

Add iterator slice helpers#791

Merged
samber merged 11 commits intosamber:masterfrom
juliazadorozhnaya:iter-slice-and-channel-helpers
Feb 23, 2026
Merged

Add iterator slice helpers#791
samber merged 11 commits intosamber:masterfrom
juliazadorozhnaya:iter-slice-and-channel-helpers

Conversation

@juliazadorozhnaya
Copy link
Copy Markdown
Contributor

@juliazadorozhnaya juliazadorozhnaya commented Jan 30, 2026

This PR is a follow‑up to the previous slice‑helpers PR. It adds iterator versions of Take, TakeWhile, and TakeFilter along with tests, examples, and docs.

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.36%. Comparing base (b6d1bf3) to head (c36b4b1).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #791      +/-   ##
==========================================
+ Coverage   94.26%   94.36%   +0.09%     
==========================================
  Files          18       18              
  Lines        2860     2891      +31     
==========================================
+ Hits         2696     2728      +32     
  Misses        149      149              
+ Partials       15       14       -1     
Flag Coverage Δ
unittests 94.36% <100.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread it/seq.go Outdated
Comment thread channel.go Outdated
Comment thread channel.go Outdated
Comment on lines +372 to +374
// Tee duplicates the stream into multiple output channels without blocking.
// If an output channel is full or not ready, the value is dropped for that channel.
func Tee[T any](count, channelsBufferCap int, upstream <-chan T) []<-chan T {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, this function is too specific.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean we should remove Tee because FanOut/FanIn already cover this, or keep it as a separate helper?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @d-enk .

Please open a new PR for further discussion.

Also: I would rename it in something more similar to FanOut: FanOutBestEffort, FanOutNonBlocking, FanOutLossy, FanOutDrop, FanOutFireAndForget, other ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I've removed the Tee function and all references to it from this PR.

Comment thread it/seq.go Outdated
Comment thread it/seq.go Outdated
@juliazadorozhnaya juliazadorozhnaya marked this pull request as draft February 8, 2026 13:31
@juliazadorozhnaya juliazadorozhnaya marked this pull request as ready for review February 20, 2026 17:36
@d-enk
Copy link
Copy Markdown
Contributor

d-enk commented Feb 21, 2026

I still find channel functions questionable.

I suggest splitting the pull request into two parts.

As it should have been from the beginning

@d-enk
Copy link
Copy Markdown
Contributor

d-enk commented Feb 21, 2026

Just as I already suggested in a private message, I propose to split Sliding explicitly

switch {
case step == size:
...
case step < size:
...
case step > size:
...
}

Comment thread it/seq.go Outdated

// TakeFilter filters elements and takes the first n elements that match the predicate.
// Equivalent to calling Take(FilterI(...)), but more efficient as it stops after finding n matches.
func TakeFilter[T any, I ~func(func(T) bool)](collection I, n int, predicate func(item T, index int) bool) I {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename it to TakeFilterI and add a TakeFilter variant please?

(also in error below + doc)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Renamed to TakeFilterI and added a TakeFilter variant.

Comment thread channel.go Outdated
Comment on lines +372 to +374
// Tee duplicates the stream into multiple output channels without blocking.
// If an output channel is full or not ready, the value is dropped for that channel.
func Tee[T any](count, channelsBufferCap int, upstream <-chan T) []<-chan T {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @d-enk .

Please open a new PR for further discussion.

Also: I would rename it in something more similar to FanOut: FanOutBestEffort, FanOutNonBlocking, FanOutLossy, FanOutDrop, FanOutFireAndForget, other ?

@juliazadorozhnaya
Copy link
Copy Markdown
Contributor Author

Just as I already suggested in a private message, I propose to split Sliding explicitly

switch {
case step == size:
...
case step < size:
...
case step > size:
...
}

Done. Sliding now uses an explicit switch on offset (step - size) for the three cases.

@d-enk
Copy link
Copy Markdown
Contributor

d-enk commented Feb 23, 2026

I'd remove Distinct/DistinctBy too.

You can also clean up the title/commits.

@d-enk
Copy link
Copy Markdown
Contributor

d-enk commented Feb 23, 2026

Can you rename it to TakeFilterI and add a TakeFilter variant please?

@samber Something went wrong somewhere

lo/slice.go

Line 12 in 921fb61

func Filter[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {

lo/slice.go

Line 653 in 921fb61

func TakeFilter[T any, Slice ~[]T](collection Slice, n int, predicate func(item T, index int) bool) Slice {

lo/slice.go

Line 713 in 921fb61

func FilterReject[T any, Slice ~[]T](collection Slice, predicate func(T, int) bool) (kept, rejected Slice) {

@juliazadorozhnaya
Copy link
Copy Markdown
Contributor Author

Can you rename it to TakeFilterI and add a TakeFilter variant please?

Something went wrong somewhere

lo/slice.go

Line 12 in 921fb61

func Filter[T any, Slice ~[]T](collection Slice, predicate func(item T, index int) bool) Slice {

lo/slice.go

Line 653 in 921fb61

func TakeFilter[T any, Slice ~[]T](collection Slice, n int, predicate func(item T, index int) bool) Slice {

lo/slice.go

Line 713 in 921fb61

func FilterReject[T any, Slice ~[]T](collection Slice, predicate func(T, int) bool) (kept, rejected Slice) {

Done. In slice.go renamed to TakeFilterI and added TakeFilter variant

@juliazadorozhnaya
Copy link
Copy Markdown
Contributor Author

I'd remove Distinct/DistinctBy too.

You can also clean up the title/commits.

Done

@juliazadorozhnaya juliazadorozhnaya changed the title Add iterator slice helpers and channel distinct/tee utilities Add iterator slice helpers Feb 23, 2026
@d-enk
Copy link
Copy Markdown
Contributor

d-enk commented Feb 23, 2026

Done. In slice.go renamed to TakeFilterI and added TakeFilter variant

#791 (comment)

This was not a call to action for you...

@samber
Copy link
Copy Markdown
Owner

samber commented Feb 23, 2026

Oops, sorry. You wrote Take(FilterI(...)) so that why i suggested TakeFilterI but lets use TakeFilter instead. Sorry for the mistake.

EDIT: I reverted the last commit.

EDIT2: Thanks to both of you. I'm targeting a new release this week.

@samber samber merged commit c1d11cb into samber:master Feb 23, 2026
2 checks passed
@d-enk
Copy link
Copy Markdown
Contributor

d-enk commented Feb 23, 2026

I completely missed that Take(Filter()) already exists

As if TakeFilter() were redundant for sequences...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants