// Copyright 2024 Matthew Rich . All rights reserved. package ds import ( "log/slog" ) type OrderedSet[Value comparable] struct { Values []*Value elements map[Value]int } func NewOrderedSet[Value comparable]() *OrderedSet[Value] { return &OrderedSet[Value]{ elements: make(map[Value]int), Values: make([]*Value, 0, 10) } } func (s *OrderedSet[Value]) Add(value Value) { slog.Info("OrderedSet.Add", "key", value, "s", s) s.Values = append(s.Values, &value) s.elements[value] = len(s.Values) slog.Info("OrderedSet.Add", "key", value, "s", s, "v", &s.Values) } func (s *OrderedSet[Value]) Delete(key Value) { slog.Info("OrderedSet.Delete", "key", key, "s", s, "size", len(s.Values)) if i, ok := s.elements[key]; ok { i-- s.Values[i] = nil delete(s.elements, key) } } func (s *OrderedSet[Value]) Contains(value Value) (result bool) { slog.Info("OrderedSet.Contains", "key", value, "s", s, "size", len(s.Values), "v", &s.Values) _, result = s.elements[value] return } func (s *OrderedSet[Value]) Len() int { return len(s.elements) } func (s *OrderedSet[Value]) AddItems(value []Value) { for _, v := range value { s.Add(v) } } func (s *OrderedSet[Value]) Items() []*Value { slog.Info("OrderedSet.Items - start", "s", s) result := make([]*Value, 0, len(s.elements) - 1) for _, v := range s.Values { slog.Info("OrderedSet.Items", "value", v) if v != nil { result = append(result, v) s.elements[*v] = len(result) } } slog.Info("OrderedSet.Items", "s", s, "result", result) s.Values = result return result }