Skip to content

Commit

Permalink
Merge pull request #25 from meian/23-repeat
Browse files Browse the repository at this point in the history
#23 repeat implements
  • Loading branch information
meian authored Jan 15, 2022
2 parents 5384653 + ebed605 commit 96e1d65
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 15 deletions.
75 changes: 64 additions & 11 deletions repeat.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,87 @@
package gcf

type repeatIteratable[T any] struct {
itb Iteratable[T]
v T
count int
}

type repeatIterator[T any] struct {
v T
count int
i int
current T
}

type repeatIteratableIteratable[T any] struct {
itb Iteratable[T]
count int
}

type repeatIteratableIterator[T any] struct {
genIt func() Iterator[T]
it Iterator[T]
count int
i int
current T
}

func Repeat[T any](itb Iteratable[T], count int) Iteratable[T] {
if itb == nil {
itb = empty[T]()
count = 0
// Repeat makes Iteratable that repeat v a count times.
//
// itb = gcf.Repeat(1, 3)
//
// If count is 0 or negative, return Iteratable with no element.
func Repeat[T any](v T, count int) Iteratable[T] {
switch {
case count < 1:
return empty[T]()
case count == 1:
return FromSlice([]T{v})
}
if count == 1 {
return itb
}
return &repeatIteratable[T]{itb, count}
return &repeatIteratable[T]{v, count}
}

func (itb *repeatIteratable[T]) Iterator() Iterator[T] {
return &repeatIterator[T]{itb.itb.Iterator, itb.itb.Iterator(), itb.count, 0, zero[T]()}
return &repeatIterator[T]{itb.v, itb.count, 0, zero[T]()}
}

func (it *repeatIterator[T]) MoveNext() bool {
if it.i >= it.count {
it.current = zero[T]()
return false
}
it.current = it.v
it.i++
return true
}

func (it *repeatIterator[T]) Current() T {
return it.current
}

// RepeatIteratable makes Iteratable that repeat elements in itb a count times.
//
// s := []int{1, 2, 3}
// itb := gcf.FromSlice(s)
// itb = gcf.RepeatIteratable(itb, 3)
//
// If count is 0 or negative, return Iteratable with no element.
func RepeatIteratable[T any](itb Iteratable[T], count int) Iteratable[T] {
switch {
case itb == nil:
return empty[T]()
case count < 1:
return empty[T]()
case count == 1:
return itb
}
return &repeatIteratableIteratable[T]{itb, count}
}

func (itb *repeatIteratableIteratable[T]) Iterator() Iterator[T] {
return &repeatIteratableIterator[T]{itb.itb.Iterator, itb.itb.Iterator(), itb.count, 0, zero[T]()}
}

func (it *repeatIteratableIterator[T]) MoveNext() bool {
if it.i >= it.count {
return false
}
Expand All @@ -44,6 +97,6 @@ func (it *repeatIterator[T]) MoveNext() bool {
return false
}

func (it *repeatIterator[T]) Current() T {
func (it *repeatIteratableIterator[T]) Current() T {
return it.current
}
73 changes: 69 additions & 4 deletions repeat_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,63 @@
package gcf_test

import (
"fmt"
"testing"

"github.com/meian/gcf"
"github.com/stretchr/testify/assert"
)

func TestRepeat(t *testing.T) {
tests := []struct {
name string
v int
count int
want []int
}{
{
name: "3 times",
v: 1,
count: 3,
want: []int{1, 1, 1},
},
{
name: "1 times",
v: 1,
count: 1,
want: []int{1},
},
{
name: "0 times",
v: 1,
count: 0,
want: []int{},
},
{
name: "negative times",
v: 1,
count: -1,
want: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
itb := gcf.Repeat(tt.v, tt.count)
s := gcf.ToSlice(itb)
assert.Equal(tt.want, s)
})
}
}

func ExampleRepeat() {
itb := gcf.Repeat(1, 3)
fmt.Println(gcf.ToSlice(itb))
// Output:
// [1 1 1]
}

func TestRepeatIteratable(t *testing.T) {
itb := gcf.FromSlice([]int{1, 2, 3})
itbe := gcf.FromSlice[int](nil)
tests := []struct {
Expand All @@ -34,25 +84,40 @@ func TestRepeat(t *testing.T) {
count: 3,
want: []int{},
},
{
name: "1 times",
itb: itb,
count: 1,
want: []int{1, 2, 3},
},
{
name: "0 times",
itb: itb,
count: 0,
want: []int{},
},
{
name: "1 times",
name: "negative times",
itb: itb,
count: 1,
want: []int{1, 2, 3},
count: -1,
want: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
itb := gcf.Repeat(tt.itb, tt.count)
itb := gcf.RepeatIteratable(tt.itb, tt.count)
s := gcf.ToSlice(itb)
assert.Equal(tt.want, s)
})
}
}

func ExampleRepeatIteratable() {
s := []int{1, 2, 3}
itb := gcf.FromSlice(s)
itb = gcf.RepeatIteratable(itb, 3)
fmt.Println(gcf.ToSlice(itb))
// Output:
// [1 2 3 1 2 3 1 2 3]
}

0 comments on commit 96e1d65

Please sign in to comment.