Skip to content

Commit

Permalink
Improve performance of Filter iters
Browse files Browse the repository at this point in the history
  • Loading branch information
BooleanCat committed Jun 30, 2024
1 parent 000c096 commit 35de6f0
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 33 deletions.
55 changes: 25 additions & 30 deletions it/filter.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,41 @@
package it

import (
"iter"

"github.com/BooleanCat/go-functional/v2/it/filter"
)
import "iter"

// Filter yields values from an iterator that satisfy a predicate.
func Filter[V any](delegate iter.Seq[V], predicate func(V) bool) iter.Seq[V] {
return func(yield func(V) bool) {
delegate, stop := iter.Pull(delegate)
defer stop()

for {
value, ok := delegate()

if !ok || predicate(value) && !yield(value) {
return
for value := range delegate {
if predicate(value) {
if !yield(value) {
return
}
}
}
}
}

// Exclude yields values from an iterator that do not satisfy a predicate.
func Exclude[V any](delegate iter.Seq[V], predicate func(V) bool) iter.Seq[V] {
return Filter[V](delegate, filter.Not[V](predicate))
return func(yield func(V) bool) {
for value := range delegate {
if !predicate(value) {
if !yield(value) {
return
}
}
}
}
}

// Filter2 yields values from an iterator that satisfy a predicate.
func Filter2[V, W any](delegate iter.Seq2[V, W], predicate func(V, W) bool) iter.Seq2[V, W] {
return func(yield func(V, W) bool) {
delegate, stop := iter.Pull2(delegate)
defer stop()

for {
left, right, ok := delegate()

if !ok || predicate(left, right) && !yield(left, right) {
return
for k, v := range delegate {
if predicate(k, v) {
if !yield(k, v) {
return
}
}
}
}
Expand All @@ -46,14 +44,11 @@ func Filter2[V, W any](delegate iter.Seq2[V, W], predicate func(V, W) bool) iter
// Exclude2 yields values from an iterator that do not satisfy a predicate.
func Exclude2[V, W any](delegate iter.Seq2[V, W], predicate func(V, W) bool) iter.Seq2[V, W] {
return func(yield func(V, W) bool) {
delegate, stop := iter.Pull2(delegate)
defer stop()

for {
left, right, ok := delegate()

if !ok || !predicate(left, right) && !yield(left, right) {
return
for k, v := range delegate {
if !predicate(k, v) {
if !yield(k, v) {
return
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions it/itx/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import (

// Filter is a convenience method for chaining [it.Filter] on [Iterator]s.
func (iterator Iterator[V]) Filter(predicate func(V) bool) Iterator[V] {
return Iterator[V](it.Filter[V](iter.Seq[V](iterator), predicate))
return Iterator[V](it.Filter(iter.Seq[V](iterator), predicate))
}

// Exclude is a convenience method for chaining [it.Exclude] on [Iterator]s.
func (iterator Iterator[V]) Exclude(predicate func(V) bool) Iterator[V] {
return Iterator[V](it.Exclude[V](iter.Seq[V](iterator), predicate))
return Iterator[V](it.Exclude(iter.Seq[V](iterator), predicate))
}

// Filter is a convenience method for chaining [it.Filter2] on [Iterator2]s.
func (iterator Iterator2[V, W]) Filter(predicate func(V, W) bool) Iterator2[V, W] {
return Iterator2[V, W](it.Filter2[V, W](iter.Seq2[V, W](iterator), predicate))
return Iterator2[V, W](it.Filter2(iter.Seq2[V, W](iterator), predicate))
}

// Exclude is a convenience method for chaining [it.Exclude2] on [Iterator2]s.
Expand Down

0 comments on commit 35de6f0

Please sign in to comment.