Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

slices: add MatchedThen and MatchedFuncThen by iter #71707

Closed
weilaaa opened this issue Feb 13, 2025 · 2 comments
Closed

slices: add MatchedThen and MatchedFuncThen by iter #71707

weilaaa opened this issue Feb 13, 2025 · 2 comments
Labels

Comments

@weilaaa
Copy link

weilaaa commented Feb 13, 2025

Background

slices provides slices.Contains() and slices.ContainsFunc(), both are convenient for determining wether a slice contains a certain element. That's great but seems not enough for common scene that need filter some matched elements in slices and do something with them. Based on this, I want to introduce two new APIs MatchedThen and MatchedFuncThen into slices/iter.

Proposal

I propose adding the following APIs to the slices package as a part of slices/iter.go.

// MatchedThen returns an iterator that yields the clements matched.
func MatchedThen[S ~[]E, E comparable](s S, v E) iter.Seq[E] {...}

// MatchedFuncThen returns an iterator that yields the clements of s satisfies f(e).
func MatchedFuncThen[S ~[]E, E comparable](s S, f func(E) bool) iter.Seq[E] {...}

Both MatchedThen and MatchedFuncThen are based on iterator, we can easily use it according to our preference, pull or push mode.

s1 := []int{1, 2, 3, 3, 4, 5}
for v := range slices.MatchedThen(s1, 3) {
	fmt.Println(v)
}
// Output:
// 3
// 3
type inr struct {
	foo int
	bar string
}
s2 := []inr{
	{1, "1"},
	{2, "2"},
	{3, "3"},
	{4, "4"},
	{5, "5"},
	{6, "6"},
}
next, stop := iter.Pull(slices.MatchedFuncThen(s2, func(inr inr) bool {
	return inr.foo%2 == 0
}))
defer stop()
for {
	v, ok := next()
	if !ok {
		break
	}
	fmt.Println(v)
}
// Output:
// {2 2}
// {4 4}
// {6 6}

Design discussion

Why iter.Seq[E] and not iter.Seq2[E]?

Iter.Seq[E] was chosen instead of iter.Seq2[E] because the resulting index after filtering would be confusing which looks discontinuous. And users usually focus on the objects themselves in the match, not the index.

@randall77
Copy link
Contributor

I think this is a dup of #61898, particularly its Filter function. Please reopen if you disagree.

@weilaaa
Copy link
Author

weilaaa commented Feb 13, 2025

I think this is a dup of #61898, particularly its Filter function. Please reopen if you disagree.

Agree with Filter function, it can be used not only for slices, but also for all iterable objects such as map, array, slice, etc, which provide iter. But if you need a dedicated filter capability used in the slices library, just like slices.All(), slices.Values(), please let me know and I will reopen this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants