diff --git a/pkg/collections/array_list/array_list_methods.go b/pkg/collections/array_list/array_list_methods.go index 6fe81a1..b5f0c96 100644 --- a/pkg/collections/array_list/array_list_methods.go +++ b/pkg/collections/array_list/array_list_methods.go @@ -4,6 +4,8 @@ import ( "errors" "fmt" "slices" + + "git.tswf.io/incredible-go/incredible-go-core/pkg/container/optional" ) func (self *ArrayList[T]) Add(element T) { @@ -190,3 +192,19 @@ func (self *ArrayList[T]) ToSlice() []T { result := slices.Clone(self.content)[:self.size] return result } + +func (self *ArrayList[T]) Find(filter func(T) bool) *optional.Optional[T] { + for index, value := range self.content { + if index >= self.size { + break + } + + passed := filter(value) + + if passed { + return optional.OfAny(value) + } + } + + return optional.Empty[T]() +} diff --git a/pkg/container/optional/optional.go b/pkg/container/optional/optional.go new file mode 100644 index 0000000..78c189d --- /dev/null +++ b/pkg/container/optional/optional.go @@ -0,0 +1,6 @@ +package optional + +type Optional[T any] struct { + Present bool + Value T +} diff --git a/pkg/container/optional/optional_factories.go b/pkg/container/optional/optional_factories.go new file mode 100644 index 0000000..c75ea95 --- /dev/null +++ b/pkg/container/optional/optional_factories.go @@ -0,0 +1,23 @@ +package optional + +func Empty[T any]() *Optional[T] { + return &Optional[T]{ + Present: false, + } +} + +func OfAny[T any](value T) *Optional[T] { + return &Optional[T]{ + Present: true, + Value: value, + } +} + +func OfNonDefault[T comparable](value T) *Optional[T] { + var defaultValue T + if value != defaultValue { + return Empty[T]() + } else { + return OfAny[T](value) + } +} diff --git a/pkg/container/optional/optional_methods.go b/pkg/container/optional/optional_methods.go new file mode 100644 index 0000000..4c99247 --- /dev/null +++ b/pkg/container/optional/optional_methods.go @@ -0,0 +1,59 @@ +package optional + +import "log" + +func (self *Optional[T]) IfPresent(action func(T)) { + if self.Present { + action(self.Value) + } +} + +func (self *Optional[T]) OrElsePanic(err error) T { + return self.OrElsePanicF(func() error { + return err + }) +} + +func (self *Optional[T]) OrElsePanicF(errorSupplier func() error) T { + if self.Present { + return self.Value + } + + err := errorSupplier() + panic(err) +} + +func (self *Optional[T]) OrElseFatal(err error) T { + return self.OrElseFatalF(func() error { + return err + }) +} + +func (self *Optional[T]) OrElseFatalF(errorSupplier func() error) T { + if self.Present { + return self.Value + } + + err := errorSupplier() + var returnStub T + log.Fatal(err) + + // Компилятор без return не пропустит, но сюда никогда не дойдет из-за фатала выше. + return returnStub +} + +func (self *Optional[T]) OrElse(defaultValue T) T { + if self.Present { + return self.Value + } + + return defaultValue +} + +func (self *Optional[T]) OrElseGet(defaultValueSupplier func() T) T { + if self.Present { + return self.Value + } + + return defaultValueSupplier() +}