Go IteratorWrapper

Date: 2024-10-21
package main

import (
	"fmt"
	"math"
)

type IteratorWrapper[T any] struct {
	iter []T
}

func From[T any](iterable []T) *IteratorWrapper[T] {
	return &IteratorWrapper[T]{iter: iterable}
}

func (iw *IteratorWrapper[T]) MapTo[U any](f func(T) U) *IteratorWrapper[U] {
	result := make([]U, len(iw.iter))
	for i, x := range iw.iter {
		result[i] = f(x)
	}
	return From(result)
}

func (iw *IteratorWrapper[T]) Filter(f func(T) bool) *IteratorWrapper[T] {
	var result []T
	for _, x := range iw.iter {
		if f(x) {
			result = append(result, x)
		}
	}
	return From(result)
}

func (iw *IteratorWrapper[T]) Take(n int) *IteratorWrapper[T] {
	if n > len(iw.iter) {
		n = len(iw.iter)
	}
	return From(iw.iter[:n])
}

func (iw *IteratorWrapper[T]) Skip(n int) *IteratorWrapper[T] {
	if n > len(iw.iter) {
		n = len(iw.iter)
	}
	return From(iw.iter[n:])
}

func (iw *IteratorWrapper[T]) ToArray() []T {
	return iw.iter
}

func (iw *IteratorWrapper[T]) First() (T, bool) {
	if len(iw.iter) == 0 {
		var zero T
		return zero, false
	}
	return iw.iter[0], true
}

func (iw *IteratorWrapper[T]) Last() (T, bool) {
	if len(iw.iter) == 0 {
		var zero T
		return zero, false
	}
	return iw.iter[len(iw.iter)-1], true
}

func (iw *IteratorWrapper[T]) Sum(f func(T) float64) float64 {
	var total float64
	for _, x := range iw.iter {
		total += f(x)
	}
	return total
}

func (iw *IteratorWrapper[T]) Min(f func(T) float64) (float64, bool) {
	if len(iw.iter) == 0 {
		return 0, false
	}
	min := f(iw.iter[0])
	for _, x := range iw.iter[1:] {
		val := f(x)
		if val < min {
			min = val
		}
	}
	return min, true
}

func (iw *IteratorWrapper[T]) Max(f func(T) float64) (float64, bool) {
	if len(iw.iter) == 0 {
		return 0, false
	}
	max := f(iw.iter[0])
	for _, x := range iw.iter[1:] {
		val := f(x)
		if val > max {
			max = val
		}
	}
	return max, true
}
func main() {
	numbers := []int{1, 2, 3, 4, 5}

	result := From(numbers).
		Map(func(x int) int { return x * 2 }).
		Filter(func(x int) bool { return x > 5 }).
		Take(3).
		ToArray()

	fmt.Println("Result:", result) // [6, 8, 10]

	first, ok := From(numbers).First()
	if ok {
		fmt.Println("First:", first)
	}

	last, ok := From(numbers).Last()
	if ok {
		fmt.Println("Last:", last)
	}

	sum := From(numbers).Sum(func(x int) float64 { return float64(x) })
	fmt.Println("Sum:", sum)

	min, ok := From(numbers).Min(func(x int) float64 { return float64(x) })
	if ok {
		fmt.Println("Min:", min)
	}

	max, ok := From(numbers).Max(func(x int) float64 { return float64(x) })
	if ok {
		fmt.Println("Max:", max)
	}
}
89770cookie-checkGo IteratorWrapper