A set library based on maps and iterators. A set type is not necessary to have set operations.
There are many mapset implementations available, but they restrict the values to struct{} or bool. Although it seems like the right abstract data type, in practice it limits the usability.
- Maps must be copied even though they already support iteration and O(1) lookup.
- Map values are lost.
- Slices must be copied even if they would have only been iterated.
- Slice ordering is lost.
- Copying effectively means no early exits, e.g., in a subset check.
Since sets are not built-in, they realistically will always be a secondary type. Even in languages with built-in sets, it is common to call set operations on keys while still keeping data in a map, and common to want to retain ordering.
So iterset is built around generic maps with any value type. Inspired by Python sets, its methods support iterators. This integrates well with functions in maps and slices, and addresses the typical mapset issues.
- Maps can be casted instead of copied.
- Map values are kept without affecting set operations.
- Slices can be iterated using
slices.Valueswithout copying. - Slice iterators retain ordering.
- Iterators are lazily evaluated, inherently supporting early exits.
There are constructors for all common use cases.
Casta mapUnique{By}iterates keys in orderCompact{By}iterates consecutive grouped keysCollectwith default valueSetfrom variadic argsIndexretains original positionCountstores key countsIndexBystores values by key functionGroup{By}stores slices grouped by keysReducecombines values grouped by keysMemoizecaches function call
Methods support iterators, compatible with slices.Values and maps.Keys. Implementations are asymptotically optimal, and exit early where relevant.
EqualIsSubsetIsSupersetIsDisjointUnionIntersectDifferenceReverseDifferenceSymmetricDifference
Some operations are also functions, to avoid making unnecessary maps. Note there is a trade-off between early exits versus iteration overhead. If one sequence is expected to be smaller, it is often faster to collect it into a map anyway.
Equal{Counts}IsSubsetIsDisjointIntersectDifferenceSorted{Union,Intersect,Difference}
Includes general sequence utilities which complement the set operations. These are subject to change as iter patterns progress.
IsEmptySizeKeysSortedMinMaxGoIter
Iterators are only single-use if their input was.
No dependencies. Go >=1.23 required.
go get github.com/coady/iterset100% code coverage.
go test -cover
go test -bench=.