2021-11-08 21:53:15 +02:00
|
|
|
package bag
|
|
|
|
|
2021-12-15 23:40:14 +02:00
|
|
|
type Bag[Item any] interface {
|
2021-11-08 21:53:15 +02:00
|
|
|
Add(Item)
|
|
|
|
Size() int
|
|
|
|
IsEmpty() bool
|
|
|
|
ForEach(func(Item))
|
|
|
|
}
|
|
|
|
|
|
|
|
// We use linked list as internal data structure
|
|
|
|
// to get O(1) speed for Add operation
|
2021-12-15 23:40:14 +02:00
|
|
|
type node[Item any] struct {
|
2021-11-08 21:53:15 +02:00
|
|
|
item Item
|
2021-12-15 23:40:14 +02:00
|
|
|
next *node[Item]
|
2021-11-08 21:53:15 +02:00
|
|
|
}
|
|
|
|
|
2021-12-15 23:40:14 +02:00
|
|
|
type bag[OfType any] struct {
|
2021-11-08 21:53:15 +02:00
|
|
|
size int
|
2021-12-15 23:40:14 +02:00
|
|
|
head *node[OfType]
|
2021-11-08 21:53:15 +02:00
|
|
|
}
|
|
|
|
|
2021-12-15 23:40:14 +02:00
|
|
|
func NewBag[OfType any]() Bag[OfType] {
|
|
|
|
return &bag[OfType]{}
|
2021-11-08 21:53:15 +02:00
|
|
|
}
|
|
|
|
|
2021-12-15 23:40:14 +02:00
|
|
|
func (b *bag[OfType]) Add(item OfType) {
|
2021-11-08 21:53:15 +02:00
|
|
|
next := b.head
|
2021-12-15 23:40:14 +02:00
|
|
|
b.head = &node[OfType]{item, next}
|
2021-11-08 21:53:15 +02:00
|
|
|
b.size++
|
|
|
|
}
|
|
|
|
|
2021-12-15 23:40:14 +02:00
|
|
|
func (b *bag[_]) Size() int {
|
2021-11-08 21:53:15 +02:00
|
|
|
return b.size
|
|
|
|
}
|
|
|
|
|
2021-12-15 23:40:14 +02:00
|
|
|
func (b *bag[_]) IsEmpty() bool {
|
2021-11-08 21:53:15 +02:00
|
|
|
return b.size == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// As for now Go doesn't have iterators.
|
|
|
|
// But we can simulate them with ForEach method
|
2021-12-15 23:40:14 +02:00
|
|
|
func (b *bag[OfType]) ForEach(f func(OfType)) {
|
2021-11-08 21:53:15 +02:00
|
|
|
for current := b.head; current != nil; current = current.next {
|
|
|
|
f(current.item)
|
|
|
|
}
|
|
|
|
}
|