package utils

// Union array1 + array2
func Union[T comparable](array1, array2 []T) []T {
	flag := make(map[T]struct{})
	var res []T

	for _, v := range array1 {
		if _, ok := flag[v]; ok {
			continue
		}
		res = append(res, v)
		flag[v] = struct{}{}
	}

	for _, v := range array2 {
		if _, ok := flag[v]; ok {
			continue
		}
		res = append(res, v)
		flag[v] = struct{}{}
	}
	return res
}

// Intersect intersect of array1 and array2
func Intersect[T comparable](array1, array2 []T) []T {
	flag := make(map[T]bool)
	var res []T

	for _, v := range array2 {
		flag[v] = false
	}

	for _, v := range array1 {
		if _flag, ok := flag[v]; !ok || _flag {
			continue
		}
		res = append(res, v)
		flag[v] = true
	}
	return res
}

// ExceptIDs array1 - array2
func Except[T comparable](array1, array2 []T) []T {
	flag := make(map[T]struct{})
	var res []T

	for _, v := range array2 {
		flag[v] = struct{}{}
	}

	for _, v := range array1 {
		if _, ok := flag[v]; ok {
			continue
		}
		res = append(res, v)
	}
	return res
}
