package util

func Transform[Tin any, Tout any](s []Tin, transformFn func(i *Tin) Tout) (out []Tout) {
	out = make([]Tout, 0)

	for _, item := range s {
		out = append(out, transformFn(&item))
	}

	return
}

func Select[T any](s []T, selectFn func(i *T) bool) (out []T) {
	out = make([]T, 0)

	for _, item := range s {
		if selectFn(&item) {
			out = append(out, item)
		}
	}

	return
}

func Map[T any, Tkey comparable, Tval any](s []T, transformFn func(i *T) (Tkey, Tval)) (out map[Tkey]Tval) {
	out = make(map[Tkey]Tval)
	for _, i := range s {
		key, val := transformFn(&i)
		out[key] = val
	}

	return
}

func Group[T any, Tkey comparable, Tval any](s []T, groupFn func(i *T) (groupKey Tkey, value Tval)) (out map[Tkey][]Tval) {
	out = make(map[Tkey][]Tval)
	for _, i := range s {
		key, value := groupFn(&i)
		list, exists := out[key]
		if !exists {
			list = make([]Tval, 0, 2)
		}

		out[key] = append(list, value)
	}

	return
}
