package set import ( "cmp" "slices" ) type OrderedSet[O cmp.Ordered] struct { Set[O] order []O } func NewOrdered[O cmp.Ordered]() *OrderedSet[O] { return &OrderedSet[O]{ Set: New[O](), order: []O{}, } } // Creates an ordered set from each item in a slice. func OrderedFromSlice[S ~[]O, O cmp.Ordered](slice S) *OrderedSet[O] { set := NewOrdered[O]() set.Add(slice...) return set } // Creates an ordered set from each key in a map. func OrderedFromMap[M ~map[O]V, O cmp.Ordered, V any](m M) *OrderedSet[O] { return OrderedFromSlice(mapKeys(m)) } // Convert an unordered set to ordered set. func OrderedFromSet[O cmp.Ordered](set Set[O]) *OrderedSet[O] { return OrderedFromSlice(set.ToSlice()) } // Convert the ordered set to an unordered set. func (ordered *OrderedSet[O]) ToSet() Set[O] { return ordered.Set } // Returns an ordered slice of the members in a set. func (ordered *OrderedSet[O]) ToSlice() []O { return ordered.order } // Adds members to the ordered set. func (ordered *OrderedSet[O]) Add(items ...O) { for _, item := range items { if !ordered.HasMember(item) { ordered.Set.Add(item) idx, _ := slices.BinarySearch(ordered.order, item) ordered.order = slices.Insert(ordered.order, idx, item) } } } // Removes members from the ordered set, if they exists. func (ordered *OrderedSet[O]) Remove(items ...O) { ordered.Set.Remove(items...) ordered.order = slices.DeleteFunc(ordered.order, func(item O) bool { return !ordered.HasMember(item) }) }