Repository: samber/lo
File: intersect.go (Go)

Code before:
				seen[lists[i][j]] = struct{}{}
				result = append(result, lists[i][j])
			}
		}
	}

	return result
}

// Without returns slice excluding all given values.
func Without[T comparable, Slice ~[]T](collection Slice, exclude ...T) Slice {
	result := make(Slice, 0, len(collection))
	for i := range collection {
		if !Contains(exclude, collection[i]) {
			result = append(result, collection[i])
		}
	}
	return result
}

// WithoutBy filters a slice by excluding elements whose extracted keys match any in the exclude list.
// It returns a new slice containing only the elements whose keys are not in the exclude list.
func WithoutBy[T any, K comparable](collection []T, extract func(item T) K, exclude ...K) []T {
	result := make([]T, 0, len(collection))
	for _, item := range collection {
		if !Contains(exclude, extract(item)) {
			result = append(result, item)
		}
	}
	return result
}

// WithoutEmpty returns slice excluding empty values.
//
// Deprecated: Use lo.Compact instead.
func WithoutEmpty[T comparable, Slice ~[]T](collection Slice) Slice {
	return Compact(collection)
}


Review comment (performance):
I'd say it's worth using sets here for better performance
```go
func WithoutBy[T any, K comparable](collection []T, extract func(item T) K, exclude ...K) []T {
	whitelist := make(map[K]struct{}, len(collection))

	for _, item := range collection {
		whitelist[extract(item)] = struct{}{}
	}

	for _, k := range exclude {
		delete(whitelist, k)
	}

	result := make([]T, 0, len(whitelist))
	for _, item := range collection {
		if _, ok := whitelist[extract(item)]; ok {
			result = append(result, item)
		}
	}

	return result
}
```

Might as well refactor existing function `Without`

Code after:
				seen[lists[i][j]] = struct{}{}
				result = append(result, lists[i][j])
			}
		}
	}

	return result
}

// Without returns slice excluding all given values.
func Without[T comparable, Slice ~[]T](collection Slice, exclude ...T) Slice {
	excludeMap := make(map[T]struct{}, len(exclude))
	for i := range exclude {
		excludeMap[exclude[i]] = struct{}{}
	}

	result := make(Slice, 0, len(collection))
	for i := range collection {
		if _, ok := excludeMap[collection[i]]; !ok {
			result = append(result, collection[i])
		}
	}
	return result
}

// WithoutBy filters a slice by excluding elements whose extracted keys match any in the exclude list.
// It returns a new slice containing only the elements whose keys are not in the exclude list.
func WithoutBy[T any, K comparable](collection []T, iteratee func(item T) K, exclude ...K) []T {
	excludeMap := make(map[K]struct{}, len(exclude))
	for _, e := range exclude {
		excludeMap[e] = struct{}{}
	}

	result := make([]T, 0, len(collection))
	for _, item := range collection {
		if _, ok := excludeMap[iteratee(item)]; !ok {
			result = append(result, item)
		}
	}
	return result
}

// WithoutEmpty returns slice excluding zero values.
//
// Deprecated: Use lo.Compact instead.
func WithoutEmpty[T comparable, Slice ~[]T](collection Slice) Slice {
	return Compact(collection)
}

// WithoutNth returns slice excluding nth value.
func WithoutNth[T comparable, Slice ~[]T](collection Slice, nths ...int) Slice {