Skip to content

Commit

Permalink
Fix return of find in repositories to error instead of boolean to be …
Browse files Browse the repository at this point in the history
…more generic

Add more methods to list
  • Loading branch information
totemcaf committed Jun 24, 2022
1 parent 99e5192 commit f329b6e
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 4 deletions.
16 changes: 16 additions & 0 deletions lists/generators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package lists

// Generate use provided generator to generate array of N elements
func Generate[T any](times int, generator func(i int) T) []T {
if times <= 0 {
return []T{}
}

elements := make([]T, times)

for idx := range elements {
elements[idx] = generator(idx)
}

return elements
}
89 changes: 89 additions & 0 deletions lists/lists.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ func Map[S any, T any](ss []S, m types.Mapper[S, T]) []T {
return tt
}

// MapNonNil apply mapper to all elements of 'ss' and return slice of all non-nil results
func MapNonNil[S any, T any](ss []S, mapper types.Mapper[S, *T]) []*T {
us := make([]*T, len(ss))

for idx, s := range ss {
if t := mapper(s); t != nil {
us[idx] = t
}
}

return us
}

func FlatMap[S any, T any](ss []S, m types.Mapper[S, []T]) []T {
tt := make([]T, 0, len(ss))
for _, s := range ss {
Expand All @@ -34,6 +47,37 @@ func Filter[S any](ss []S, p types.Predicate[S]) []S {
return tt
}

// FilterNot removes (filter out) all elements the satisfies predicate
func FilterNot[S any](ss []S, p types.Predicate[S]) []S {
var tt []S
for _, s := range ss {
if !p(s) {
tt = append(tt, s)
}
}
return tt
}

// Remove all occurrences of the given element from the slice
func Remove[T types.Comparable[T]](ts []T, toRemove T) []T {
return FilterNot(ts, func(t T) bool { return toRemove.Compare(t) == 0 })
}

// Any returns true if at lease one element satisfies predicate
func Any[T any](ts []T, predicate func(t T) bool) bool {
for _, t := range ts {
if predicate(t) {
return true
}
}
return false
}

// FilterNonNil returns all the elements of array that are non nil
func FilterNonNil[T any](ts []*T) []*T {
return Filter(ts, func(t *T) bool { return t != nil })
}

func Count[S any](ss []S, p types.Predicate[S]) int {
var count = 0
for _, s := range ss {
Expand Down Expand Up @@ -81,3 +125,48 @@ func IndexBy2[S any](ss []S, p types.Predicate[S]) (int, bool) {
idx := IndexBy(ss, p)
return idx, idx >= 0
}

func Has[T types.Comparable[T]](ts []T, other T) bool {
for _, t := range ts {
if t.Compare(other) == 0 {
return true
}
}
return false
}

func Has2[T comparable](ts []T, other T) bool {
for _, t := range ts {
if t == other {
return true
}
}
return false
}

func DeepCloneSlice[T types.Cloneable[T]](source []T) []T {
return Map(source, func(t T) T { return t.Clone() })
}

func CloneSlice[T any](source []T) []T {
target := make([]T, len(source))

copy(target, source)

return target
}

func Reduce[Value any, Element any](
initialValue Value,
elements []Element,
reducer func(Value, Element) Value,
) Value {

accum := initialValue

for _, element := range elements {
accum = reducer(accum, element)
}

return accum
}
9 changes: 9 additions & 0 deletions nils/nils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nils

func IsNil(t *any) bool {
return t == nil
}

func IsNotNil(t *any) bool {
return t != nil
}
8 changes: 4 additions & 4 deletions repositories/in_memory_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,21 @@ func (r *InMemoryRepository[Key, Entity]) Delete(key Key) error {
return nil
}

func (r *InMemoryRepository[Key, Entity]) FindById(key Key) (Entity, bool) {
func (r *InMemoryRepository[Key, Entity]) FindById(key Key) (Entity, error) {
r.lock.RLock()
defer r.lock.RUnlock()
r.init()

if !r.AllowEmptyKey && key == r.emptyKey {
var entity Entity
return entity, false
return entity, invalidKey
}

if entity, found := r.elementsById[key]; found {
return entity, true
return entity, nil
}
var empty Entity
return empty, false
return empty, notFound
}

func (r *InMemoryRepository[Key, Entity]) FindBy(predicate types.Predicate[Entity]) []Entity {
Expand Down
9 changes: 9 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,12 @@ type Iterable[T any] interface {
ForEach(Function1[T])
Iterator() Iterator[T]
}

type Cloneable[T any] interface {
Clone() T
}

type Comparable[T any] interface {
// Compare returns -1, 0, 1 if this is less than, equal to, to greater than other
Compare(other T) int
}

0 comments on commit f329b6e

Please sign in to comment.