David K. Bainbridge | 528b318 | 2017-01-23 08:51:59 -0800 | [diff] [blame^] | 1 | // Copyright 2014 Canonical Ltd. |
| 2 | // Licensed under the LGPLv3, see LICENCE file for details. |
| 3 | |
| 4 | package set |
| 5 | |
| 6 | import ( |
| 7 | "sort" |
| 8 | ) |
| 9 | |
| 10 | // Ints represents the classic "set" data structure, and contains ints. |
| 11 | type Ints map[int]bool |
| 12 | |
| 13 | // NewInts creates and initializes an Ints and populates it with |
| 14 | // initial values as specified in the parameters. |
| 15 | func NewInts(initial ...int) Ints { |
| 16 | result := make(Ints) |
| 17 | for _, value := range initial { |
| 18 | result.Add(value) |
| 19 | } |
| 20 | return result |
| 21 | } |
| 22 | |
| 23 | // Size returns the number of elements in the set. |
| 24 | func (is Ints) Size() int { |
| 25 | return len(is) |
| 26 | } |
| 27 | |
| 28 | // IsEmpty is true for empty or uninitialized sets. |
| 29 | func (is Ints) IsEmpty() bool { |
| 30 | return len(is) == 0 |
| 31 | } |
| 32 | |
| 33 | // Add puts a value into the set. |
| 34 | func (is Ints) Add(value int) { |
| 35 | if is == nil { |
| 36 | panic("uninitalised set") |
| 37 | } |
| 38 | is[value] = true |
| 39 | } |
| 40 | |
| 41 | // Remove takes a value out of the set. If value wasn't in the set to start |
| 42 | // with, this method silently succeeds. |
| 43 | func (is Ints) Remove(value int) { |
| 44 | delete(is, value) |
| 45 | } |
| 46 | |
| 47 | // Contains returns true if the value is in the set, and false otherwise. |
| 48 | func (is Ints) Contains(value int) bool { |
| 49 | _, exists := is[value] |
| 50 | return exists |
| 51 | } |
| 52 | |
| 53 | // Values returns an unordered slice containing all the values in the set. |
| 54 | func (is Ints) Values() []int { |
| 55 | result := make([]int, len(is)) |
| 56 | i := 0 |
| 57 | for key := range is { |
| 58 | result[i] = key |
| 59 | i++ |
| 60 | } |
| 61 | return result |
| 62 | } |
| 63 | |
| 64 | // SortedValues returns an ordered slice containing all the values in the set. |
| 65 | func (is Ints) SortedValues() []int { |
| 66 | values := is.Values() |
| 67 | sort.Ints(values) |
| 68 | return values |
| 69 | } |
| 70 | |
| 71 | // Union returns a new Ints representing a union of the elments in the |
| 72 | // method target and the parameter. |
| 73 | func (is Ints) Union(other Ints) Ints { |
| 74 | result := make(Ints) |
| 75 | // Use the internal map rather than going through the friendlier functions |
| 76 | // to avoid extra allocation of slices. |
| 77 | for value := range is { |
| 78 | result[value] = true |
| 79 | } |
| 80 | for value := range other { |
| 81 | result[value] = true |
| 82 | } |
| 83 | return result |
| 84 | } |
| 85 | |
| 86 | // Intersection returns a new Ints representing a intersection of the elments in the |
| 87 | // method target and the parameter. |
| 88 | func (is Ints) Intersection(other Ints) Ints { |
| 89 | result := make(Ints) |
| 90 | // Use the internal map rather than going through the friendlier functions |
| 91 | // to avoid extra allocation of slices. |
| 92 | for value := range is { |
| 93 | if other.Contains(value) { |
| 94 | result[value] = true |
| 95 | } |
| 96 | } |
| 97 | return result |
| 98 | } |
| 99 | |
| 100 | // Difference returns a new Ints representing all the values in the |
| 101 | // target that are not in the parameter. |
| 102 | func (is Ints) Difference(other Ints) Ints { |
| 103 | result := make(Ints) |
| 104 | // Use the internal map rather than going through the friendlier functions |
| 105 | // to avoid extra allocation of slices. |
| 106 | for value := range is { |
| 107 | if !other.Contains(value) { |
| 108 | result[value] = true |
| 109 | } |
| 110 | } |
| 111 | return result |
| 112 | } |