Description
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.