Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
= Comfy Gopher - Collections

image:https://codecov.io/gh/comfygopher/collections/graph/badge.svg?token=I5QQ2SU3E7[codecov,link=https://codecov.io/gh/comfygopher/collections]

image:https://img.shields.io/coderabbit/prs/github/comfygopher/collections?utm_source=oss&utm_medium=github&utm_campaign=comfygopher%2Fcollections&labelColor=171717&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews[CodeRabbit Pull Request Reviews]
image:https://img.shields.io/coderabbit/prs/github/comfygopher/collections?utm_source=oss&utm_medium=github&utm_campaign=comfygopher%2Fcollections&labelColor=5b5b5b&color=FF570A&link=https%3A%2F%2Fcoderabbit.ai&label=CodeRabbit+Reviews[CodeRabbit Pull Request Reviews]
image:https://goreportcard.com/badge/github.com/comfygopher/collections[Go Report Card,link=https://goreportcard.com/report/github.com/comfygopher/collections]

== What is Comfy Gopher?

Expand Down
143 changes: 121 additions & 22 deletions base_cases_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -766,18 +766,18 @@ func getFoldCases(builder baseCollIntBuilder) []*baseTestCase {
coll: builder.Empty(),
args: baseIntArgs{
reducer: func(acc int, i int, current int) int {
return acc + current
return acc*10 + current
},
initial: 0,
initial: 100,
},
want1: 0,
want1: 100,
},
{
name: "Fold() on one-item collection",
coll: builder.One(),
args: baseIntArgs{
reducer: func(acc int, i int, current int) int {
return acc + current
return acc*10 + current
},
initial: 0,
},
Expand All @@ -788,22 +788,22 @@ func getFoldCases(builder baseCollIntBuilder) []*baseTestCase {
coll: builder.Three(),
args: baseIntArgs{
reducer: func(acc int, i int, current int) int {
return acc + current
return acc*10 + current
},
initial: 100,
},
want1: 766,
want1: 113653,
},
{
name: "Fold() on three-item collection, include index",
coll: builder.Three(),
args: baseIntArgs{
reducer: func(acc int, i int, current int) int {
return acc + i + current
return acc*(i+1) + current
},
initial: 100,
},
want1: 100 + 0 + 111 + 1 + 222 + 2 + 333,
want1: ((100+111)*2+222)*3 + 333,
},
}
}
Expand All @@ -820,6 +820,67 @@ func testFold(t *testing.T, builder baseCollIntBuilder) {
}
}

func getFoldRevCases(builder baseCollIntBuilder) []*baseTestCase {
return []*baseTestCase{
{
name: "FoldRev() on empty collection",
coll: builder.Empty(),
args: baseIntArgs{
reducer: func(acc int, _ int, current int) int {
return acc*10 + current
},
initial: 100,
},
want1: 100,
},
{
name: "FoldRev() on one-item collection",
coll: builder.One(),
args: baseIntArgs{
reducer: func(acc int, _ int, current int) int {
return acc*10 + current
},
initial: 100,
},
want1: 1111,
},
{
name: "FoldRev() on three-item collection",
coll: builder.Three(),
args: baseIntArgs{
reducer: func(acc int, _ int, current int) int {
return acc*10 + current
},
initial: 100,
},
want1: 135631,
},
{
name: "FoldRev() on three-item collection, include index",
coll: builder.Three(),
args: baseIntArgs{
reducer: func(acc int, i int, current int) int {
return acc*(i+1) + current
},
initial: 100,
},
want1: ((100*3+333)*2 + 222) + 111,
},
}
}

func testFoldRev(t *testing.T, builder baseCollIntBuilder) {
cases := getFoldRevCases(builder)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
got := tt.coll.FoldRev(tt.args.reducer, tt.args.initial)
if !reflect.DeepEqual(got, tt.want1) {
t.Errorf("FoldRev() = %v, want1 %v", got, tt.want1)
}
})
}
}

func getIsEmptyCases(builder baseCollIntBuilder) []baseTestCase {
return []baseTestCase{
{
Expand Down Expand Up @@ -889,47 +950,85 @@ func getReduceCases(t *testing.T, builder baseCollIntBuilder) []*baseTestCase {
{
name: "Reduce() on empty collection",
coll: builder.Empty(),
args: baseIntArgs{reducer: func(acc int, i int, current int) int {
return acc + current
args: baseIntArgs{reducer: func(acc int, _ int, current int) int {
return acc*10 + current
}},
want1: 0,
want2: ErrEmptyCollection,
},
{
name: "Fold() on one-item collection",
coll: builder.One(),
args: baseIntArgs{reducer: func(acc int, i int, current int) int {
return acc + current
args: baseIntArgs{reducer: func(acc int, _ int, current int) int {
return acc*10 + current
}},
want1: 111,
want2: nil,
},
{
name: "Fold() on three-item collection",
coll: builder.Three(),
args: baseIntArgs{reducer: func(acc int, i int, current int) int {
return acc + current
args: baseIntArgs{reducer: func(acc int, _ int, current int) int {
return acc*10 + current
}},
want1: 666,
want1: 13653,
want2: nil,
},
}
}

func testReduce(t *testing.T, builder baseCollIntBuilder) {
cases := getReduceCases(t, builder)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
got1, got2 := tt.coll.Reduce(tt.args.reducer)
if !reflect.DeepEqual(got1, tt.want1) {
t.Errorf("Reduce() = %v, want1 %v", got1, tt.want1)
}
if !reflect.DeepEqual(got2, tt.want2) {
t.Errorf("Reduce() = %v, want1 %v", got2, tt.want2)
}
})
}
}

func getReduceRevCases(t *testing.T, builder baseCollIntBuilder) []*baseTestCase {
return []*baseTestCase{
{
name: "Fold() on three-item collection, include index",
name: "Reduce() on empty collection",
coll: builder.Empty(),
args: baseIntArgs{reducer: func(acc int, _ int, current int) int {
return acc*10 + current
}},
want1: 0,
want2: ErrEmptyCollection,
},
{
name: "Fold() on one-item collection",
coll: builder.One(),
args: baseIntArgs{reducer: func(acc int, _ int, current int) int {
return acc*10 + current
}},
want1: 111,
want2: nil,
},
{
name: "Fold() on three-item collection",
coll: builder.Three(),
args: baseIntArgs{reducer: func(acc int, i int, current int) int {
return acc + i + current
args: baseIntArgs{reducer: func(acc int, _ int, current int) int {
return acc*10 + current
}},
want1: 0 + 111 + 1 + 222 + 2 + 333,
want1: 35631,
want2: nil,
},
}
}

func testReduce(t *testing.T, builder baseCollIntBuilder) {
cases := getReduceCases(t, builder)
func testReduceRev(t *testing.T, builder baseCollIntBuilder) {
cases := getReduceRevCases(t, builder)
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
got1, got2 := tt.coll.Reduce(tt.args.reducer)
got1, got2 := tt.coll.ReduceRev(tt.args.reducer)
if !reflect.DeepEqual(got1, tt.want1) {
t.Errorf("Reduce() = %v, want1 %v", got1, tt.want1)
}
Expand Down
4 changes: 2 additions & 2 deletions definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ type Base[V any] interface {
// See: SearchRev
FindLast(predicate Predicate[V], defaultValue V) V
Fold(reducer Reducer[V], initial V) (result V)
// FoldRev(reducer Reducer[V], initial V) (result V) // TODO
FoldRev(reducer Reducer[V], initial V) (result V)
IsEmpty() bool
Len() int
Search(predicate Predicate[V]) (val V, found bool)
// SearchLastPos(predicate Predicate[V]) (val V, found bool) // TODO
// SearchPos(predicate Predicate[V]) (val V, found bool) // TODO
SearchRev(predicate Predicate[V]) (val V, found bool)
Reduce(reducer Reducer[V]) (result V, err error)
// ReduceRev(reducer Reducer[V]) (result V, err error) // TODO
ReduceRev(reducer Reducer[V]) (result V, err error)
ToSlice() []V
Values() iter.Seq[V]
// ValuesRev() iter.Seq[V] // TODO
Expand Down
28 changes: 2 additions & 26 deletions functions.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,10 @@
package coll

// public API:
// Public:

// Copy creates a copy of the given collection.
func Copy[C baseInternal[V], V any](c C) C {
//var it V
//
//if _, ok := interface{}(it).(cmp.Cmp); ok {
// // c is of type CmpSequence[V]
//}

return c.copy().(C)

//switch v := any(c).(type) {
//case *comfySeq[V]:
// return c.copy().(C)
//case *comfyCmpSeq[any]:
// return c.copy().(C)
//}

// check if c is of type Sequence[C]:
//if cl, ok := any(c).(*comfySeq[V]); ok {
// s := make([]V, len(cl.s))
// for _, v := range cl.s {
// s = append(s, v)
// }
// c := &comfySeq[V]{
// s: s,
// }
// return any(c).(C)
//}
}

//// Filter creates a new, filtered collection from the given collection.
Expand All @@ -38,6 +13,7 @@ func Copy[C baseInternal[V], V any](c C) C {
//}
//
//// MapTo creates a new, mapped collection from the given collection.
// Maybe this should be called "Transform"? Maybe "MapTo" should be an alias for "Transform"?
//func MapTo[OUT Indexed[N], IN Indexed[V], V, N any](coll IN, transformer func(int, V) N) OUT {
// panic("not implemented")
//}
Expand Down
8 changes: 8 additions & 0 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ func (c *comfyMap[K, V]) Fold(reducer Reducer[Pair[K, V]], initial Pair[K, V]) P
return comfyFoldSlice(c.s, reducer, initial)
}

func (c *comfyMap[K, V]) FoldRev(reducer Reducer[Pair[K, V]], initial Pair[K, V]) Pair[K, V] {
return comfyFoldSliceRev(c.s, reducer, initial)
}

func (c *comfyMap[K, V]) Get(k K) (V, bool) {
pair, ok := c.m[k]
if !ok {
Expand Down Expand Up @@ -202,6 +206,10 @@ func (c *comfyMap[K, V]) Reduce(reducer Reducer[Pair[K, V]]) (Pair[K, V], error)
return comfyReduceSlice(c.s, reducer)
}

func (c *comfyMap[K, V]) ReduceRev(reducer Reducer[Pair[K, V]]) (Pair[K, V], error) {
return comfyReduceSliceRev(c.s, reducer)
}

func (c *comfyMap[K, V]) Remove(k K) {
c.remove(k)
}
Expand Down
Loading
Loading