Skip to content

slices: add MatchedThen and MatchedFuncThen by iter #71707

Closed
@weilaaa

Description

@weilaaa

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions