func (s Slice) Find(f func(el T) bool) (T, error) {
	for _, el := range s.Data {
		if f(el) {
			return el, nil
		}
	}
	var tmp T
	return tmp, ErrNotFound
}
Find returns the first element for which f returns true
package implementation
import (
	"fmt"
	"math/rand"
	"sort"
	"strings"
	"time"
)
type Slice struct {
	Data []T
}
func (s Slice) Any(f func(el T) bool) bool {
	for _, el := range s.Data {
		if f(el) {
			return true
		}
	}
	return false
}
func (s Slice) All(f func(el T) bool) bool {
	for _, el := range s.Data {
		if !f(el) {
			return false
		}
	}
	return true
}
func (s Slice) Choice(seed int64) (T, error) {
	if len(s.Data) == 0 {
		var tmp T
		return tmp, ErrEmpty
	}
	if seed == 0 {
		seed = time.Now().UnixNano()
	}
	rand.Seed(seed)
	i := rand.Intn(len(s.Data))
	return s.Data[i], nil
}
func (s Slice) ChunkBy(f func(el T) G) [][]T {
	chunks := make([][]T, 0)
	if len(s.Data) == 0 {
		return chunks
	}
	chunk := make([]T, 0)
	prev := f(s.Data[0])
	chunk = append(chunk, s.Data[0])
	for _, el := range s.Data[1:] {
		curr := f(el)
		if curr != prev {
			chunks = append(chunks, chunk)
			chunk = make([]T, 0)
			prev = curr
		}
		chunk = append(chunk, el)
	}
	if len(chunk) > 0 {
		chunks = append(chunks, chunk)
	}
	return chunks
}
func (s Slice) ChunkEvery(count int) ([][]T, error) {
	chunks := make([][]T, 0)
	if count <= 0 {
		return chunks, ErrNegativeValue
	}
	chunk := make([]T, 0, count)
	for i, el := range s.Data {
		chunk = append(chunk, el)
		if (i+1)%count == 0 {
			chunks = append(chunks, chunk)
			chunk = make([]T, 0, count)
		}
	}
	if len(chunk) > 0 {
		chunks = append(chunks, chunk)
	}
	return chunks, nil
}
func (s Slice) Contains(el T) bool {
	for _, val := range s.Data {
		if val == el {
			return true
		}
	}
	return false
}
func (s Slice) Count(el T) int {
	count := 0
	for _, val := range s.Data {
		if val == el {
			count++
		}
	}
	return count
}
func (s Slice) CountBy(f func(el T) bool) int {
	count := 0
	for _, el := range s.Data {
		if f(el) {
			count++
		}
	}
	return count
}
func (s Slice) Cycle() chan T {
	c := make(chan T, 1)
	go func() {
		defer close(c)
		if len(s.Data) == 0 {
			return
		}
		for {
			for _, val := range s.Data {
				c <- val
			}
		}
	}()
	return c
}
func (s Slice) Dedup() []T {
	if len(s.Data) == 0 {
		return s.Data
	}
	result := make([]T, 0, len(s.Data))
	prev := s.Data[0]
	result = append(result, prev)
	for _, el := range s.Data[1:] {
		if el != prev {
			result = append(result, el)
			prev = el
		}
	}
	return result
}
func (s Slice) DedupBy(f func(el T) G) []T {
	result := make([]T, 0, len(s.Data))
	if len(s.Data) == 0 {
		return result
	}
	prev := f(s.Data[0])
	result = append(result, s.Data[0])
	for _, el := range s.Data[1:] {
		curr := f(el)
		if curr != prev {
			result = append(result, el)
			prev = curr
		}
	}
	return result
}
func (s Slice) Delete(element T) []T {
	if len(s.Data) == 0 {
		return s.Data
	}
	result := make([]T, 0, len(s.Data))
	deleted := false
	for _, el := range s.Data {
		if !deleted && el == element {
			deleted = true
			continue
		}
		result = append(result, el)
	}
	return result
}
func (s Slice) DeleteAll(element T) []T {
	if len(s.Data) == 0 {
		return s.Data
	}
	result := make([]T, 0, len(s.Data))
	for _, el := range s.Data {
		if el == element {
			continue
		}
		result = append(result, el)
	}
	return result
}
func (s Slice) DeleteAt(indices ...int) ([]T, error) {
	if len(indices) == 0 || len(s.Data) == 0 {
		return s.Data, nil
	}
	for _, index := range indices {
		if index >= len(s.Data) {
			return s.Data, ErrOutOfRange
		}
	}
	result := make([]T, 0, len(s.Data)-1)
	for i, el := range s.Data {
		add := true
		for _, index := range indices {
			if i == index {
				add = false
				break
			}
		}
		if add {
			result = append(result, el)
		}
	}
	return result, nil
}
func (s Slice) DropEvery(nth int, from int) ([]T, error) {
	if nth <= 0 {
		return s.Data, ErrNonPositiveValue
	}
	if from < 0 {
		return s.Data, ErrNegativeValue
	}
	result := make([]T, 0, len(s.Data)/nth)
	for i, el := range s.Data {
		if (i+from)%nth != 0 {
			result = append(result, el)
		}
	}
	return result, nil
}
func (s Slice) DropWhile(f func(el T) bool) []T {
	for i, el := range s.Data {
		if !f(el) {
			return s.Data[i:]
		}
	}
	return []T{}
}
func (s Slice) Each(f func(el T)) {
	for _, el := range s.Data {
		f(el)
	}
}
func (s Slice) EndsWith(suffix []T) bool {
	if len(suffix) > len(s.Data) {
		return false
	}
	start := len(s.Data) - len(suffix)
	for i, el := range suffix {
		if el != s.Data[start+i] {
			return false
		}
	}
	return true
}
func (s Slice) Equal(other []T) bool {
	if len(s.Data) != len(other) {
		return false
	}
	for i, el := range other {
		if s.Data[i] != el {
			return false
		}
	}
	return true
}
func (s Slice) Filter(f func(el T) bool) []T {
	result := make([]T, 0, len(s.Data))
	for _, el := range s.Data {
		if f(el) {
			result = append(result, el)
		}
	}
	return result
}