From fcf4eff5b2d18ad045f095784f4b09c4aae6bf87 Mon Sep 17 00:00:00 2001 From: kitamin <11195207+meian@users.noreply.github.com> Date: Sun, 16 Jan 2022 03:31:29 +0900 Subject: [PATCH 1/2] #23 rename Repeat to RepeatIteratable --- repeat.go | 34 +++++++++++++++++++++------------- repeat_test.go | 26 +++++++++++++++++++++----- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/repeat.go b/repeat.go index 121428e..ff4c40b 100644 --- a/repeat.go +++ b/repeat.go @@ -1,11 +1,11 @@ package gcf -type repeatIteratable[T any] struct { +type repeatIteratableIteratable[T any] struct { itb Iteratable[T] count int } -type repeatIterator[T any] struct { +type repeatIteratableIterator[T any] struct { genIt func() Iterator[T] it Iterator[T] count int @@ -13,22 +13,30 @@ type repeatIterator[T any] struct { current T } -func Repeat[T any](itb Iteratable[T], count int) Iteratable[T] { - if itb == nil { - itb = empty[T]() - count = 0 - } - if count == 1 { +// 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 &repeatIteratable[T]{itb, count} + return &repeatIteratableIteratable[T]{itb, count} } -func (itb *repeatIteratable[T]) Iterator() Iterator[T] { - return &repeatIterator[T]{itb.itb.Iterator, itb.itb.Iterator(), itb.count, 0, zero[T]()} +func (itb *repeatIteratableIteratable[T]) Iterator() Iterator[T] { + return &repeatIteratableIterator[T]{itb.itb.Iterator, itb.itb.Iterator(), itb.count, 0, zero[T]()} } -func (it *repeatIterator[T]) MoveNext() bool { +func (it *repeatIteratableIterator[T]) MoveNext() bool { if it.i >= it.count { return false } @@ -44,6 +52,6 @@ func (it *repeatIterator[T]) MoveNext() bool { return false } -func (it *repeatIterator[T]) Current() T { +func (it *repeatIteratableIterator[T]) Current() T { return it.current } diff --git a/repeat_test.go b/repeat_test.go index bf6e5c2..ff11891 100644 --- a/repeat_test.go +++ b/repeat_test.go @@ -1,13 +1,14 @@ package gcf_test import ( + "fmt" "testing" "github.com/meian/gcf" "github.com/stretchr/testify/assert" ) -func TestRepeat(t *testing.T) { +func TestRepeatIteratable(t *testing.T) { itb := gcf.FromSlice([]int{1, 2, 3}) itbe := gcf.FromSlice[int](nil) tests := []struct { @@ -34,6 +35,12 @@ 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, @@ -41,18 +48,27 @@ func TestRepeat(t *testing.T) { 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] +} From ebed6054eb31f61fb2e5e14fb9fe733ee515efd1 Mon Sep 17 00:00:00 2001 From: kitamin <11195207+meian@users.noreply.github.com> Date: Sun, 16 Jan 2022 06:07:46 +0900 Subject: [PATCH 2/2] #23 Add Repeat implements --- repeat.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ repeat_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/repeat.go b/repeat.go index ff4c40b..49649a0 100644 --- a/repeat.go +++ b/repeat.go @@ -1,5 +1,17 @@ package gcf +type repeatIteratable[T any] struct { + 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 @@ -13,6 +25,39 @@ type repeatIteratableIterator[T any] struct { current T } +// 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}) + } + return &repeatIteratable[T]{v, count} +} + +func (itb *repeatIteratable[T]) Iterator() Iterator[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} diff --git a/repeat_test.go b/repeat_test.go index ff11891..abc52e0 100644 --- a/repeat_test.go +++ b/repeat_test.go @@ -8,6 +8,55 @@ import ( "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)