github.com/coveo/gotemplate@v2.7.7+incompatible/collections/implementation/list_helper.go (about) 1 package implementation 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/coveo/gotemplate/collections" 8 ) 9 10 func (l baseList) String() string { return fmt.Sprint(l.AsArray()) } 11 func (l baseList) PrettyPrint() string { return l.String() } 12 13 // ListHelper implements basic functionalities required for IGenericList. 14 type ListHelper struct { 15 BaseHelper 16 } 17 18 // Add adds elements at the end of the supplied list. 19 func (lh ListHelper) Add(list baseIList, prepend bool, objects ...interface{}) baseIList { 20 array := list.AsArray() 21 for i := range objects { 22 objects[i] = lh.Convert(objects[i]) 23 } 24 if prepend { 25 array, objects = objects, array 26 } 27 return lh.AsList(append(array, objects...)) 28 } 29 30 // Clone returns a copy of the supplied list. 31 func (lh ListHelper) Clone(list baseIList) baseIList { 32 return lh.NewList(list.AsArray()...) 33 } 34 35 // GetIndexes returns the element at position index in the list. If index is out of bound, nil is returned. 36 func (lh ListHelper) GetIndexes(list baseIList, indexes ...int) interface{} { 37 switch len(indexes) { 38 case 0: 39 return nil 40 case 1: 41 index := indexes[0] 42 if index < 0 { 43 // If index is negative, we try to get from the end 44 index += list.Len() 45 } 46 if index < 0 || index >= list.Len() { 47 return nil 48 } 49 return (list.AsArray())[index] 50 } 51 result := list.Create(len(indexes)) 52 for i := range indexes { 53 result.Set(i, lh.GetIndexes(list, indexes[i])) 54 } 55 return result 56 } 57 58 // GetStrings returns a string array representation of the list. 59 func (lh ListHelper) GetStrings(list baseIList) []string { 60 return collections.ToStrings(list.AsArray()) 61 } 62 63 // GetStringArray returns a StringArray representation of the list. 64 func (lh ListHelper) GetStringArray(list baseIList) strArray { 65 result := make(strArray, list.Len()) 66 for i := 0; i < list.Len(); i++ { 67 result[i] = str(fmt.Sprint(list.Get(i))) 68 } 69 return result 70 } 71 72 // NewList creates a new IGenericList from supplied arguments. 73 func (bh BaseHelper) NewList(items ...interface{}) baseIList { 74 if len(items) == 1 && items[0] != nil { 75 v := reflect.ValueOf(items[0]) 76 switch v.Kind() { 77 case reflect.Array, reflect.Slice: 78 // There is only one items and it is an array or a slice 79 items = make([]interface{}, v.Len()) 80 for i := 0; i < v.Len(); i++ { 81 items[i] = v.Index(i).Interface() 82 } 83 } 84 } 85 newList := bh.CreateList(0, len(items)) 86 for i := range items { 87 newList = newList.Append(items[i]) 88 } 89 return newList 90 } 91 92 // NewStringList creates a new IGenericList from supplied arguments. 93 func (bh BaseHelper) NewStringList(items ...string) baseIList { 94 newList := bh.CreateList(0, len(items)) 95 for i := range items { 96 newList = newList.Append(items[i]) 97 } 98 return newList 99 } 100 101 // Reverse returns a copy of the current list in reverse order. 102 func (lh ListHelper) Reverse(list baseIList) baseIList { 103 source := list.AsArray() 104 target := lh.CreateList(list.Len()) 105 for i := range source { 106 target.Set(target.Len()-i-1, source[i]) 107 } 108 return lh.ConvertList(target) 109 } 110 111 // SetIndex sets the value at position index into the list. If list is not large enough, it is enlarged to fit the index. 112 func (lh ListHelper) SetIndex(list baseIList, index int, value interface{}) (baseIList, error) { 113 if index < 0 { 114 return nil, fmt.Errorf("index must be positive number") 115 } 116 for list.Len() <= index { 117 list = lh.Add(list, false, nil) 118 } 119 list.AsArray()[index] = lh.Convert(value) 120 return list, nil 121 } 122 123 // Register the implementation of list functions 124 var _ = func() int { 125 collections.ListHelper = baseListHelper 126 return 0 127 }() 128 129 // Unique returns a copy of the list removing all duplicate elements. 130 func (lh ListHelper) Unique(list baseIList) baseIList { 131 source := list.AsArray() 132 target := lh.CreateList(0, list.Len()) 133 for i := range source { 134 if !target.Contains(source[i]) { 135 target = target.Append(source[i]) 136 } 137 } 138 return target 139 } 140 141 // Intersect returns a new list that is the result of the intersection of the list and the parameters. 142 func (lh ListHelper) Intersect(list baseIList, values ...interface{}) baseIList { 143 source := list.Unique().AsArray() 144 include := collections.AsList(values) 145 target := lh.CreateList(0, include.Len()) 146 for i := range source { 147 if include.Contains(source[i]) { 148 target = target.Append(source[i]) 149 } 150 } 151 return target 152 } 153 154 // Remove returns a new list without the element specified. 155 func (lh ListHelper) Remove(list baseIList, indexes ...int) baseIList { 156 for i, index := range indexes { 157 if index < 0 { 158 indexes[i] += list.Len() 159 } 160 } 161 discard := collections.AsList(indexes) 162 target := list.Create(0, list.Len()) 163 for i := range list.AsArray() { 164 if !discard.Contains(i) { 165 target = target.Append(list.Get(i)) 166 } 167 } 168 return target 169 } 170 171 // Without returns a copy of the list removing specified elements. 172 func (lh ListHelper) Without(list baseIList, values ...interface{}) baseIList { 173 source := list.AsArray() 174 exclude := collections.AsList(values) 175 target := lh.CreateList(0, list.Len()) 176 for i := range source { 177 if !exclude.Contains(source[i]) { 178 target = target.Append(source[i]) 179 } 180 } 181 return target 182 } 183 184 // Contains indicates if the list contains all specified elements 185 func (lh ListHelper) Contains(list baseIList, values ...interface{}) bool { 186 source := list.AsArray() 187 for _, value := range values { 188 match := false 189 for _, item := range source { 190 if fmt.Sprint(value) == fmt.Sprint(item) { 191 match = true 192 break 193 } 194 } 195 if !match { 196 return false 197 } 198 } 199 200 return len(source) > 0 201 }