Skip to content

Commit

Permalink
add SliceIter
Browse files Browse the repository at this point in the history
  • Loading branch information
kazhuravlev committed Sep 3, 2024
1 parent 67c9d5b commit 7a7e0c0
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
47 changes: 47 additions & 0 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,53 @@ func Slice2Iter[T any](in []T) func(func(int, T) bool) {
}
}

type IterContext interface {
// Idx returns an element index
Idx() int
RevIdx() int
IsFirst() bool
IsLast() bool
}

type iterContext struct {
idx int
inLen int
}

func (i iterContext) Idx() int {
return i.idx
}

func (i iterContext) RevIdx() int {
return i.inLen - i.idx - 1
}

func (i iterContext) IsFirst() bool {
return i.idx == 0
}

func (i iterContext) IsLast() bool {
return i.idx == i.inLen-1
}

var _ IterContext = (*iterContext)(nil)

// SliceIter create an iterator from slice. The first argument will contain a useful context struct.
func SliceIter[T any](in []T) func(func(IterContext, T) bool) {
return func(yield func(loop IterContext, elem T) bool) {
inLen := len(in)
for i := range in {
ctx := iterContext{
idx: i,
inLen: inLen,
}
if !yield(ctx, in[i]) {
return
}
}
}
}

// SliceShuffle will shuffle the slice in-place.
func SliceShuffle[T any](in []T) {
for i := range in {
Expand Down
26 changes: 26 additions & 0 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package just_test

import (
"errors"
"iter"

Check failure on line 5 in slice_test.go

View workflow job for this annotation

GitHub Actions / Build on golang 1.20 and ubuntu-latest

package iter is not in GOROOT (/opt/hostedtoolcache/go/1.20.14/x64/src/iter)

Check failure on line 5 in slice_test.go

View workflow job for this annotation

GitHub Actions / Build on golang 1.21 and ubuntu-latest

package iter is not in std (/opt/hostedtoolcache/go/1.21.13/x64/src/iter)
"strconv"
"testing"
"time"
Expand Down Expand Up @@ -1862,3 +1863,28 @@ func TestSliceLastN(t *testing.T) {
})
}
}

func TestSliceIter(t *testing.T) {
t.Parallel()

f := func(next func() (just.IterContext, int, bool), val, idx, revIdx int, isFirst, isLast bool) {
t.Helper()

iterCtx, elem, valid := next()
require.True(t, valid)
assert.Equal(t, val, elem)
assert.Equal(t, idx, iterCtx.Idx())
assert.Equal(t, revIdx, iterCtx.RevIdx())
assert.Equal(t, isFirst, iterCtx.IsFirst())
assert.Equal(t, isLast, iterCtx.IsLast())
}

in := []int{10, 20, 30, 40}
iterator := just.SliceIter(in)
next, _ := iter.Pull2(iterator)

f(next, 10, 0, 3, true, false)
f(next, 20, 1, 2, false, false)
f(next, 30, 2, 1, false, false)
f(next, 40, 3, 0, false, true)
}

0 comments on commit 7a7e0c0

Please sign in to comment.