├── .codecov.yml ├── .github ├── pull_request_template.md └── workflows │ └── ci.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── contains.go ├── contains_test.go ├── copy.go ├── copy_test.go ├── deduplicate.go ├── deduplicate_test.go ├── delete.go ├── delete_test.go ├── deleterange.go ├── deleterange_test.go ├── filter.go ├── filter_test.go ├── go.mod ├── go.sum ├── max.go ├── max_test.go ├── min.go ├── min_test.go ├── pop.go ├── pop_test.go ├── reverse.go ├── reverse_test.go ├── shuffle.go ├── shuffle_test.go ├── sum.go └── sum_test.go /.codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | enabled: yes 6 | target: 100 7 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | **Make sure that you've checked the boxes below before you submit PR that adds a new operation:** 2 | 3 | - [ ] I implemented the operation for all applicable types 4 | - [ ] I put all code in a seperate .go file named after the operation 5 | - [ ] I included tests for all functions 6 | - [ ] I documented all functions 7 | - [ ] I named all functions using the OperationType convention. For example MinInt32 instead of Int32Min 8 | - [ ] I included one testable example at the end of the test file 9 | - [ ] I added a simple example in the Example section of Readme 10 | - [ ] I updated the Operations section of Readme 11 | 12 | Thanks for your PR, you're awesome! :+1: 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: [push] 3 | 4 | jobs: 5 | golangci: 6 | strategy: 7 | matrix: 8 | go-version: [1.14.x] 9 | platform: [ubuntu-latest] 10 | name: golangci-lint 11 | runs-on: ${{ matrix.platform }} 12 | steps: 13 | - uses: actions/checkout@v1 14 | with: 15 | fetch-depth: 1 16 | - uses: actions/setup-go@v1 17 | with: 18 | go-version: ${{ matrix.go-version }} 19 | - run: | 20 | docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.24.0 golangci-lint run -v 21 | tests: 22 | strategy: 23 | matrix: 24 | go-version: [1.11.x, 1.12.x, 1.13.x, 1.14.x] 25 | platform: [ubuntu-latest, macos-latest, windows-latest] 26 | name: tests 27 | runs-on: ${{ matrix.platform }} 28 | steps: 29 | - uses: actions/checkout@v1 30 | with: 31 | fetch-depth: 1 32 | - uses: actions/setup-go@v1 33 | with: 34 | go-version: ${{ matrix.go-version }} 35 | - run: | 36 | go test -v -race -cover 37 | coverage: 38 | strategy: 39 | matrix: 40 | go-version: [1.14.x] 41 | platform: [ubuntu-latest] 42 | name: coverage 43 | runs-on: ${{ matrix.platform }} 44 | steps: 45 | - uses: actions/checkout@v1 46 | with: 47 | fetch-depth: 1 48 | - uses: actions/setup-go@v1 49 | with: 50 | go-version: ${{ matrix.go-version }} 51 | - run: | 52 | go test -v -race -cover -coverprofile=coverage.txt -covermode=atomic ./... 53 | - name: Upload coverage to Codecov 54 | uses: codecov/codecov-action@v1.0.5 55 | with: 56 | token: ${{secrets.CODECOV_TOKEN}} 57 | file: ./coverage.txt 58 | flags: unittests 59 | name: codecov-umbrella 60 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) 5 | 6 | ## [v0.2.0] 2020-02-27 7 | ### Added 8 | - Delete operation 9 | - DeleteRange operation 10 | - Pop operation 11 | - Shuffle operation 12 | - Tests on Go 1.14 13 | 14 | ## [v0.1.0] 2019-12-03 15 | ### Added 16 | - Contains operation 17 | - Copy operation 18 | - Deduplicate operation 19 | - Filter operation 20 | - Max operation 21 | - Min operation 22 | - Reverse operation 23 | - Shuffle operation 24 | - Sum operation 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Pantelis Sampaziotis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Build Status](https://github.com/psampaz/slice/workflows/build/badge.svg) 2 | [![codecov](https://codecov.io/gh/psampaz/slice/branch/master/graph/badge.svg)](https://codecov.io/gh/psampaz/slice) 3 | [![GoDoc](https://godoc.org/github.com/psampaz/slice?status.svg)](https://godoc.org/github.com/psampaz/slice) 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/psampaz/slice)](https://goreportcard.com/report/github.com/psampaz/slice) 5 | [![golangci](https://golangci.com/badges/github.com/psampaz/slice.svg)](https://golangci.com/r/github.com/psampaz/slice) 6 | 7 | Type-safe functions for common Go slice operations. 8 | 9 | # Installation 10 | 11 | ``` 12 | go get github.com/psampaz/slice 13 | ``` 14 | 15 | # Operations 16 | 17 | ✔ = Supported 18 | 19 | ✕ = Non supported 20 | 21 | \- = Not yet implemented 22 | 23 | | | bool | byte | complex(all) | float(all) | int(all) | string | uint(all) | uintptr | 24 | | ----------- | ---- | ---- | ------------ | ---------- | -------- | ------ | --------- | ------- | 25 | | Batch | - | - | - | - | - | - | - | - | 26 | | Contains | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 27 | | Copy | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 28 | | Deduplicate | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 29 | | Delete | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 30 | | DeleteRange | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 31 | | Filter | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 32 | | Insert | - | - | - | - | - | - | - | - | 33 | | Max | ✕ | ✔ | ✕ | ✔ | ✔ | ✕ | ✔ | ✔ | 34 | | Min | ✕ | ✔ | ✕ | ✔ | ✔ | ✕ | ✔ | ✔ | 35 | | Pop | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 36 | | Push | - | - | - | - | - | - | - | - | 37 | | Reverse | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 38 | | Shift | - | - | - | - | - | - | - | - | 39 | | Shuffle | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | 40 | | Sum | ✕ | ✔ | ✔ | ✔ | ✔ | ✕ | ✔ | ✔ | 41 | | Unshift | - | - | - | - | - | - | - | - | 42 | 43 | # Examples 44 | 45 | ## slice.Deduplicate 46 | 47 | Deduplicate performs order preserving, in place deduplication of a slice 48 | ```go 49 | a := []int{1, 2, 3, 2, 5, 3} 50 | a = slice.DeduplicateInt(a) // [1, 2, 3, 5] 51 | ``` 52 | 53 | ## slice.Delete 54 | 55 | Delete removes an element at a specific index of a slice. An error is return in case the index is out of bounds or the slice is nil or empty. 56 | ```go 57 | a := []int{1, 2, 3, 4, 5} 58 | a, err = slice.DeleteInt(a, 2) // [1, 2, 4, 5], nil 59 | ``` 60 | 61 | ## slice.DeleteRange 62 | 63 | DeleteRange deletes the elements between from and to index (inclusive) from a slice. An error is return in case the index is out of bounds or the slice is nil or empty. 64 | ```go 65 | a := []int{1, 2, 3, 4, 5} 66 | a, err = slice.DeleteRangeInt(a, 2, 3) // [1, 2, 5], nil 67 | ``` 68 | 69 | ## slice.Contains 70 | 71 | Contains checks if a specific value exists in a slice. 72 | ```go 73 | a := []int{1, 2, 3, 4, 5} 74 | exists := slice.ContainsInt(a, 3) // true 75 | ``` 76 | 77 | ## slice.Copy 78 | 79 | Copy creates a copy of a slice. 80 | The resulting slice has the same elements as the original but the underlying array is different. 81 | See https://github.com/go101/go101/wiki 82 | ```go 83 | a := []int{1, 2, 3, 4} 84 | b := slice.CopyInt(a) // [1, 2, 3, 4] 85 | ``` 86 | 87 | ## slice.Filter 88 | 89 | Filter performs in place filtering of a slice based on a predicate 90 | ```go 91 | a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 92 | keep := func(x int) bool { 93 | return x%2 == 0 94 | } 95 | a = slice.FilterInt(a, keep) // [2, 4, 6, 8, 10] 96 | ``` 97 | 98 | ## slice.Max 99 | 100 | Max returns the maximum value of a slice or an error in case of a nil or empty slice. 101 | ```go 102 | a := []int{1, 2, 3, 0, 4, 5} 103 | max, err := slice.MaxInt(a) // 5, nil 104 | ``` 105 | 106 | ## slice.Min 107 | 108 | Min returns the minimum value of a slice or an error in case of a nil or empty slice. 109 | ```go 110 | a := []int{1, 2, 3, 0, 4, 5} 111 | min, err := slice.MinInt(a) // 0, nil 112 | ``` 113 | 114 | ## slice.Pop 115 | 116 | Pop removes and returns the last value a slice and the remaining slice. An error is returned in case of a nil or empty slice. 117 | ```go 118 | a := []int{1, 2, 3, 4, 5} 119 | v, a, err := slice.PopInt(a) // 5, [1, 2, 3, 4], nil 120 | ``` 121 | 122 | ## slice.Reverse 123 | 124 | Reverse performs in place reversal of a slice 125 | ```go 126 | a := []int{1, 2, 3, 4, 5} 127 | a = slice.ReverseInt(a) // [5, 4, 3, 2, 1] 128 | ``` 129 | 130 | ## slice.Shuffle 131 | 132 | Shuffle shuffles (in place) a slice 133 | ```go 134 | a := []int{1, 2, 3, 4, 5} 135 | a = slice.ShuffleInt(a) // [3, 5, 1, 4, 2] (random output) 136 | ``` 137 | 138 | ## slice.Sum 139 | 140 | Sum returns the sum of the values of a slice or an error in case of a nil or empty slice 141 | 142 | ```go 143 | a := []int{1, 2, 3} 144 | sum, err := slice.SumInt(a) // 6, nil 145 | ``` 146 | 147 | # Tests 148 | 149 | if you want to run the test suite for this library: 150 | 151 | ```go 152 | $ go test -v -cover 153 | ``` 154 | 155 | # Credits 156 | 157 | - SliceTricks (https://github.com/golang/go/wiki/SliceTricks). This was the inspiration behind this library. 158 | - Genny (https://github.com/cheekybits/genny). In order to speedup the development and avoid massive copy paste, the excellent Genny library was used. 159 | 160 | # Contributing 161 | 162 | You are very welcome to contribute new operations or bug fixes in this library. 163 | 164 | ## Contribution guidelines (code) 165 | 166 | 1. Use only functions. This is a function based library so struct based operations will not be accepted, in order to preserve simplicity and consistency. 167 | 168 | 2. If the operation is not working on a nil or empty slice, then the function should return an error. 169 | 170 | 3. If the operation accepts slice indexes as parameters, then the function should guard against out of bound index values and return an error in that case. 171 | 172 | 4. All operations should be in place operations, meaning that they should alter the original slice. 173 | 174 | 5. Each function should have precise documentation. 175 | 176 | 6. Each operation should live in each own file. Example: 177 | 178 | ``` 179 | min.go 180 | min_test.go 181 | ``` 182 | 7. The naming convention for functions is OperationType. Example: 183 | 184 | ``` 185 | MinInt32() 186 | ``` 187 | 188 | instead of 189 | 190 | ``` 191 | Int32Min() 192 | ``` 193 | 8. Implement ALL applicable types in the same PR. 194 | 195 | 9. Include one testable example for Int type at the end of the test file. 196 | 197 | 10. Include one example in the Examples section of README 198 | 199 | 11. Update the table in the Operation section of README 200 | 201 | 12. Update the UNRELEASED section of CHANGELOG 202 | 203 | ## Contribution guidelines (tests) 204 | 205 | 1. All code should be 100% covered with tests 206 | 2. All operations should be tested for 3 scenarios at least: 207 | 1. nil slice 208 | 2. empty slice 209 | 3. non empty slice 210 | 211 | ## Static code analysis 212 | 213 | golangci.com runs on all PRs. Code is checked with golint, go vet, gofmt, plus 20+ linters, and review comments will be automatically added in your PR in case of a failure. You can see the whole list of linters here: https://golangci.com/product#linters 214 | 215 | ## Steps for contributing new operations 216 | 217 | 1. Open an issue describing the new operation, the proposed name and the applicable types. 218 | 2. If the operation is approved to be included in the library, create a small PR the implementation and test for only only type. 219 | 3. After code review you can proceed the implementation for the rest types. This is necessary because if you submit a PR with the implementation and test for all types, a small correction during review could eventually lead to a big refactor due to code duplication. 220 | 221 | ## Using Genny for fast implementation of all types of an operation (Optional) 222 | 223 | The following steps are an example of how to use [https://github.com/cheekybits/genny](Genny) to implement the min operation: 224 | 225 | 1. Install Genny 226 | 227 | ``` 228 | go get github.com/cheekybits/genny 229 | ``` 230 | 231 | 2. Create a file named min_genny.go 232 | 233 | ```go 234 | package slice 235 | 236 | import ( 237 | "errors" 238 | "github.com/cheekybits/genny/generic" 239 | ) 240 | 241 | type Type generic.Type 242 | 243 | // MinType returns the minimum value of an Type slice or an error in case of a nil or empty slice 244 | func MinType(a []Type) (Type, error) { 245 | if len(a) == 0 { 246 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 247 | } 248 | 249 | min := a[0] 250 | for k := 1; k < len(a); k++ { 251 | if a[k] < min { 252 | min = a[k] 253 | } 254 | } 255 | 256 | return min, nil 257 | } 258 | ``` 259 | 260 | 3. Use genny to generate code for all Go's built in types: 261 | 262 | ``` 263 | cat min_genny.go | genny gen Type=BUILTINS > min.go 264 | ``` 265 | 266 | This step will generate a file min.go with the following content: 267 | 268 | ```go 269 | package slice 270 | 271 | import "errors" 272 | 273 | // MinByte returns the minimum value of a byte slice or an error in case of a nil or empty slice 274 | func MinByte(a []byte) (byte, error) { 275 | if len(a) == 0 { 276 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 277 | } 278 | 279 | min := a[0] 280 | for k := 1; k < len(a); k++ { 281 | if a[k] < min { 282 | min = a[k] 283 | } 284 | } 285 | 286 | return min, nil 287 | } 288 | 289 | // MinFloat32 returns the minimum value of a float32 slice or an error in case of a nil or empty slice 290 | func MinFloat32(a []float32) (float32, error) { 291 | if len(a) == 0 { 292 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 293 | } 294 | 295 | min := a[0] 296 | for k := 1; k < len(a); k++ { 297 | if a[k] < min { 298 | min = a[k] 299 | } 300 | } 301 | 302 | return min, nil 303 | } 304 | . 305 | . 306 | . 307 | . 308 | ``` 309 | 310 | 4. Delete the implementation for all types not applicable for the operation 311 | 312 | 5. Create a file named min_genny_test.go 313 | 314 | ```go 315 | package slice 316 | 317 | import ( 318 | "fmt" 319 | "testing" 320 | ) 321 | 322 | func TestMinType(t *testing.T) { 323 | type args struct { 324 | a []Type 325 | } 326 | tests := []struct { 327 | name string 328 | args args 329 | want Type 330 | wantErr bool 331 | }{ 332 | { 333 | name: "nil slice", 334 | args: args{ 335 | a: nil, 336 | }, 337 | want: 0, 338 | wantErr: true, 339 | }, 340 | { 341 | name: "empty slice", 342 | args: args{ 343 | a: []Type{}, 344 | }, 345 | want: 0, 346 | wantErr: true, 347 | }, 348 | { 349 | name: "non empty slice", 350 | args: args{ 351 | a: []Type{1, 3, 2, 0, 5, 4}, 352 | }, 353 | want: 0, 354 | wantErr: false, 355 | }, 356 | } 357 | for _, tt := range tests { 358 | t.Run(tt.name, func(t *testing.T) { 359 | got, err := MinType(tt.args.a) 360 | if (err != nil) != tt.wantErr { 361 | t.Errorf("MinType() error = %v, wantErr %v", err, tt.wantErr) 362 | return 363 | } 364 | if got != tt.want { 365 | t.Errorf("MinType() = %v, want %v", got, tt.want) 366 | } 367 | }) 368 | } 369 | } 370 | 371 | ``` 372 | 373 | 6. Use genny to generate tests for all Go's built in types: 374 | 375 | ``` 376 | cat min_genny_test.go | genny gen Type=BUILTINS > min_test.go 377 | ``` 378 | 379 | This step will generate a file min_test.go with tests for each one of Go's built in types. 380 | 381 | 7. Remove tests for non applicable types. 382 | 383 | 8. Adjust the tests for each one of the types. 384 | 385 | 9. Delete min_genny.go and min_genny_test.go 386 | 387 | -------------------------------------------------------------------------------- /contains.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | // ContainsBool checks if a value exists in a bool slice 4 | func ContainsBool(a []bool, x bool) bool { 5 | if len(a) == 0 { 6 | return false 7 | } 8 | for k := range a { 9 | if a[k] == x { 10 | return true 11 | } 12 | } 13 | return false 14 | } 15 | 16 | // ContainsByte checks if a value exists in a byte slice 17 | func ContainsByte(a []byte, x byte) bool { 18 | if len(a) == 0 { 19 | return false 20 | } 21 | for k := range a { 22 | if a[k] == x { 23 | return true 24 | } 25 | } 26 | return false 27 | } 28 | 29 | // ContainsComplex64 checks if a value exists in a complex64 slice 30 | func ContainsComplex64(a []complex64, x complex64) bool { 31 | if len(a) == 0 { 32 | return false 33 | } 34 | for k := range a { 35 | if a[k] == x { 36 | return true 37 | } 38 | } 39 | return false 40 | } 41 | 42 | // ContainsComplex128 checks if a value exists in a complex128 slice 43 | func ContainsComplex128(a []complex128, x complex128) bool { 44 | if len(a) == 0 { 45 | return false 46 | } 47 | for k := range a { 48 | if a[k] == x { 49 | return true 50 | } 51 | } 52 | return false 53 | } 54 | 55 | // ContainsFloat32 checks if a value exists in a float32 slice 56 | func ContainsFloat32(a []float32, x float32) bool { 57 | if len(a) == 0 { 58 | return false 59 | } 60 | for k := range a { 61 | if a[k] == x { 62 | return true 63 | } 64 | } 65 | return false 66 | } 67 | 68 | // ContainsFloat64 checks if a value exists in a float64 slice 69 | func ContainsFloat64(a []float64, x float64) bool { 70 | if len(a) == 0 { 71 | return false 72 | } 73 | for k := range a { 74 | if a[k] == x { 75 | return true 76 | } 77 | } 78 | return false 79 | } 80 | 81 | // ContainsInt checks if a value exists in an int slice 82 | func ContainsInt(a []int, x int) bool { 83 | if len(a) == 0 { 84 | return false 85 | } 86 | for k := range a { 87 | if a[k] == x { 88 | return true 89 | } 90 | } 91 | return false 92 | } 93 | 94 | // ContainsInt16 checks if a value exists in an int16 slice 95 | func ContainsInt16(a []int16, x int16) bool { 96 | if len(a) == 0 { 97 | return false 98 | } 99 | for k := range a { 100 | if a[k] == x { 101 | return true 102 | } 103 | } 104 | return false 105 | } 106 | 107 | // ContainsInt32 checks if a value exists in an int32 slice 108 | func ContainsInt32(a []int32, x int32) bool { 109 | if len(a) == 0 { 110 | return false 111 | } 112 | for k := range a { 113 | if a[k] == x { 114 | return true 115 | } 116 | } 117 | return false 118 | } 119 | 120 | // ContainsInt64 checks if a value exists in an int64 slice 121 | func ContainsInt64(a []int64, x int64) bool { 122 | if len(a) == 0 { 123 | return false 124 | } 125 | for k := range a { 126 | if a[k] == x { 127 | return true 128 | } 129 | } 130 | return false 131 | } 132 | 133 | // ContainsInt8 checks if a value exists in an int8 slice 134 | func ContainsInt8(a []int8, x int8) bool { 135 | if len(a) == 0 { 136 | return false 137 | } 138 | for k := range a { 139 | if a[k] == x { 140 | return true 141 | } 142 | } 143 | return false 144 | } 145 | 146 | // ContainsRune checks if a value exists in a rune slice 147 | func ContainsRune(a []rune, x rune) bool { 148 | if len(a) == 0 { 149 | return false 150 | } 151 | for k := range a { 152 | if a[k] == x { 153 | return true 154 | } 155 | } 156 | return false 157 | } 158 | 159 | // ContainsString checks if a value exists in a string slice 160 | func ContainsString(a []string, x string) bool { 161 | if len(a) == 0 { 162 | return false 163 | } 164 | for k := range a { 165 | if a[k] == x { 166 | return true 167 | } 168 | } 169 | return false 170 | } 171 | 172 | // ContainsUint checks if a value exists in a uint slice 173 | func ContainsUint(a []uint, x uint) bool { 174 | if len(a) == 0 { 175 | return false 176 | } 177 | for k := range a { 178 | if a[k] == x { 179 | return true 180 | } 181 | } 182 | return false 183 | } 184 | 185 | // ContainsUint8 checks if a value exists in a uint8 slice 186 | func ContainsUint8(a []uint8, x uint8) bool { 187 | if len(a) == 0 { 188 | return false 189 | } 190 | for k := range a { 191 | if a[k] == x { 192 | return true 193 | } 194 | } 195 | return false 196 | } 197 | 198 | // ContainsUint16 checks if a value exists in a uint16 slice 199 | func ContainsUint16(a []uint16, x uint16) bool { 200 | if len(a) == 0 { 201 | return false 202 | } 203 | for k := range a { 204 | if a[k] == x { 205 | return true 206 | } 207 | } 208 | return false 209 | } 210 | 211 | // ContainsUint32 checks if a value exists in a uint32 slice 212 | func ContainsUint32(a []uint32, x uint32) bool { 213 | if len(a) == 0 { 214 | return false 215 | } 216 | for k := range a { 217 | if a[k] == x { 218 | return true 219 | } 220 | } 221 | return false 222 | } 223 | 224 | // ContainsUint64 checks if a value exists in a uint64 slice 225 | func ContainsUint64(a []uint64, x uint64) bool { 226 | if len(a) == 0 { 227 | return false 228 | } 229 | for k := range a { 230 | if a[k] == x { 231 | return true 232 | } 233 | } 234 | return false 235 | } 236 | 237 | // ContainsUintptr checks if a value exists in a uintptr slice 238 | func ContainsUintptr(a []uintptr, x uintptr) bool { 239 | if len(a) == 0 { 240 | return false 241 | } 242 | for k := range a { 243 | if a[k] == x { 244 | return true 245 | } 246 | } 247 | return false 248 | } 249 | -------------------------------------------------------------------------------- /copy.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | // CopyBool creates a copy of a bool slice. 4 | // The resulting slice has the same elements as the original but the underlying array is different. 5 | // See https://github.com/go101/go101/wiki 6 | func CopyBool(a []bool) []bool { 7 | return append(a[:0:0], a...) 8 | } 9 | 10 | // CopyByte creates a copy of a byte slice. 11 | // The resulting slice has the same elements as the original but the underlying array is different. 12 | // See https://github.com/go101/go101/wiki 13 | func CopyByte(a []byte) []byte { 14 | return append(a[:0:0], a...) 15 | } 16 | 17 | // CopyComplex128 creates a copy of a complex128 slice. 18 | // The resulting slice has the same elements as the original but the underlying array is different. 19 | // See https://github.com/go101/go101/wiki 20 | func CopyComplex128(a []complex128) []complex128 { 21 | return append(a[:0:0], a...) 22 | } 23 | 24 | // CopyComplex64 creates a copy of a complex64 slice. 25 | // The resulting slice has the same elements as the original but the underlying array is different. 26 | // See https://github.com/go101/go101/wiki 27 | func CopyComplex64(a []complex64) []complex64 { 28 | return append(a[:0:0], a...) 29 | } 30 | 31 | // CopyFloat32 creates a copy of a float32 slice. 32 | // The resulting slice has the same elements as the original but the underlying array is different. 33 | // See https://github.com/go101/go101/wiki 34 | func CopyFloat32(a []float32) []float32 { 35 | return append(a[:0:0], a...) 36 | } 37 | 38 | // CopyFloat64 creates a copy of a float64 slice. 39 | // The resulting slice has the same elements as the original but the underlying array is different. 40 | // See https://github.com/go101/go101/wiki 41 | func CopyFloat64(a []float64) []float64 { 42 | return append(a[:0:0], a...) 43 | } 44 | 45 | // CopyInt creates a copy of an int slice. 46 | // The resulting slice has the same elements as the original but the underlying array is different. 47 | // See https://github.com/go101/go101/wiki 48 | func CopyInt(a []int) []int { 49 | return append(a[:0:0], a...) 50 | } 51 | 52 | // CopyInt16 creates a copy of an int16 slice. 53 | // The resulting slice has the same elements as the original but the underlying array is different. 54 | // See https://github.com/go101/go101/wiki 55 | func CopyInt16(a []int16) []int16 { 56 | return append(a[:0:0], a...) 57 | } 58 | 59 | // CopyInt32 creates a copy of an int32 slice. 60 | // The resulting slice has the same elements as the original but the underlying array is different. 61 | // See https://github.com/go101/go101/wiki 62 | func CopyInt32(a []int32) []int32 { 63 | return append(a[:0:0], a...) 64 | } 65 | 66 | // CopyInt64 creates a copy of an int64 slice. 67 | // The resulting slice has the same elements as the original but the underlying array is different. 68 | // See https://github.com/go101/go101/wiki 69 | func CopyInt64(a []int64) []int64 { 70 | return append(a[:0:0], a...) 71 | } 72 | 73 | // CopyInt8 creates a copy of an int8 slice. 74 | // The resulting slice has the same elements as the original but the underlying array is different. 75 | // See https://github.com/go101/go101/wiki 76 | func CopyInt8(a []int8) []int8 { 77 | return append(a[:0:0], a...) 78 | } 79 | 80 | // CopyRune creates a copy of a rune slice. 81 | // The resulting slice has the same elements as the original but the underlying array is different. 82 | // See https://github.com/go101/go101/wiki 83 | func CopyRune(a []rune) []rune { 84 | return append(a[:0:0], a...) 85 | } 86 | 87 | // CopyString creates a copy of a string slice. 88 | // The resulting slice has the same elements as the original but the underlying array is different. 89 | // See https://github.com/go101/go101/wiki 90 | func CopyString(a []string) []string { 91 | return append(a[:0:0], a...) 92 | } 93 | 94 | // CopyUint creates a copy of a uint slice. 95 | // The resulting slice has the same elements as the original but the underlying array is different. 96 | // See https://github.com/go101/go101/wiki 97 | func CopyUint(a []uint) []uint { 98 | return append(a[:0:0], a...) 99 | } 100 | 101 | // CopyUint16 creates a copy of a uint16 slice. 102 | // The resulting slice has the same elements as the original but the underlying array is different. 103 | // See https://github.com/go101/go101/wiki 104 | func CopyUint16(a []uint16) []uint16 { 105 | return append(a[:0:0], a...) 106 | } 107 | 108 | // CopyUint32 creates a copy of a uint32 slice. 109 | // The resulting slice has the same elements as the original but the underlying array is different. 110 | // See https://github.com/go101/go101/wiki 111 | func CopyUint32(a []uint32) []uint32 { 112 | return append(a[:0:0], a...) 113 | } 114 | 115 | // CopyUint64 creates a copy of a uint64 slice. 116 | // The resulting slice has the same elements as the original but the underlying array is different. 117 | // See https://github.com/go101/go101/wiki 118 | func CopyUint64(a []uint64) []uint64 { 119 | return append(a[:0:0], a...) 120 | } 121 | 122 | // CopyUint8 creates a copy of a uint8 slice. 123 | // The resulting slice has the same elements as the original but the underlying array is different. 124 | // See https://github.com/go101/go101/wiki 125 | func CopyUint8(a []uint8) []uint8 { 126 | return append(a[:0:0], a...) 127 | } 128 | 129 | // CopyUintptr creates a copy of a uintptr slice. 130 | // The resulting slice has the same elements as the original but the underlying array is different. 131 | // See https://github.com/go101/go101/wiki 132 | func CopyUintptr(a []uintptr) []uintptr { 133 | return append(a[:0:0], a...) 134 | } 135 | -------------------------------------------------------------------------------- /deduplicate.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | // DeduplicateBool performs order preserving, in place deduplication of a bool slice 4 | func DeduplicateBool(a []bool) []bool { 5 | if len(a) < 2 { 6 | return a 7 | } 8 | 9 | seen := make(map[bool]struct{}) 10 | 11 | j := 0 12 | for k := range a { 13 | if _, ok := seen[a[k]]; ok { 14 | continue 15 | } 16 | seen[a[k]] = struct{}{} 17 | a[j] = a[k] 18 | j++ 19 | } 20 | 21 | return a[:j] 22 | } 23 | 24 | // DeduplicateByte performs order preserving, in place deduplication of a byte slice 25 | func DeduplicateByte(a []byte) []byte { 26 | if len(a) < 2 { 27 | return a 28 | } 29 | 30 | seen := make(map[byte]struct{}) 31 | 32 | j := 0 33 | for k := range a { 34 | if _, ok := seen[a[k]]; ok { 35 | continue 36 | } 37 | seen[a[k]] = struct{}{} 38 | a[j] = a[k] 39 | j++ 40 | } 41 | 42 | return a[:j] 43 | } 44 | 45 | // DeduplicateComplex128 performs order preserving, in place deduplication of a complex128 slice 46 | func DeduplicateComplex128(a []complex128) []complex128 { 47 | if len(a) < 2 { 48 | return a 49 | } 50 | 51 | seen := make(map[complex128]struct{}) 52 | 53 | j := 0 54 | for k := range a { 55 | if _, ok := seen[a[k]]; ok { 56 | continue 57 | } 58 | seen[a[k]] = struct{}{} 59 | a[j] = a[k] 60 | j++ 61 | } 62 | 63 | return a[:j] 64 | } 65 | 66 | // DeduplicateComplex64 performs order preserving, in place deduplication of a complex64 slice 67 | func DeduplicateComplex64(a []complex64) []complex64 { 68 | if len(a) < 2 { 69 | return a 70 | } 71 | 72 | seen := make(map[complex64]struct{}) 73 | 74 | j := 0 75 | for k := range a { 76 | if _, ok := seen[a[k]]; ok { 77 | continue 78 | } 79 | seen[a[k]] = struct{}{} 80 | a[j] = a[k] 81 | j++ 82 | } 83 | 84 | return a[:j] 85 | } 86 | 87 | // DeduplicateFloat32 performs order preserving, in place deduplication of a float32 slice 88 | func DeduplicateFloat32(a []float32) []float32 { 89 | if len(a) < 2 { 90 | return a 91 | } 92 | 93 | seen := make(map[float32]struct{}) 94 | 95 | j := 0 96 | for k := range a { 97 | if _, ok := seen[a[k]]; ok { 98 | continue 99 | } 100 | seen[a[k]] = struct{}{} 101 | a[j] = a[k] 102 | j++ 103 | } 104 | 105 | return a[:j] 106 | } 107 | 108 | // DeduplicateFloat64 performs order preserving, in place deduplication of a float64 slice 109 | func DeduplicateFloat64(a []float64) []float64 { 110 | if len(a) < 2 { 111 | return a 112 | } 113 | 114 | seen := make(map[float64]struct{}) 115 | 116 | j := 0 117 | for k := range a { 118 | if _, ok := seen[a[k]]; ok { 119 | continue 120 | } 121 | seen[a[k]] = struct{}{} 122 | a[j] = a[k] 123 | j++ 124 | } 125 | 126 | return a[:j] 127 | } 128 | 129 | // DeduplicateInt performs order preserving, in place deduplication of a int slice 130 | func DeduplicateInt(a []int) []int { 131 | if len(a) < 2 { 132 | return a 133 | } 134 | 135 | seen := make(map[int]struct{}) 136 | 137 | j := 0 138 | for k := range a { 139 | if _, ok := seen[a[k]]; ok { 140 | continue 141 | } 142 | seen[a[k]] = struct{}{} 143 | a[j] = a[k] 144 | j++ 145 | } 146 | 147 | return a[:j] 148 | } 149 | 150 | // DeduplicateInt16 performs order preserving, in place deduplication of a int16 slice 151 | func DeduplicateInt16(a []int16) []int16 { 152 | if len(a) < 2 { 153 | return a 154 | } 155 | 156 | seen := make(map[int16]struct{}) 157 | 158 | j := 0 159 | for k := range a { 160 | if _, ok := seen[a[k]]; ok { 161 | continue 162 | } 163 | seen[a[k]] = struct{}{} 164 | a[j] = a[k] 165 | j++ 166 | } 167 | 168 | return a[:j] 169 | } 170 | 171 | // DeduplicateInt32 performs order preserving, in place deduplication of a int32 slice 172 | func DeduplicateInt32(a []int32) []int32 { 173 | if len(a) < 2 { 174 | return a 175 | } 176 | 177 | seen := make(map[int32]struct{}) 178 | 179 | j := 0 180 | for k := range a { 181 | if _, ok := seen[a[k]]; ok { 182 | continue 183 | } 184 | seen[a[k]] = struct{}{} 185 | a[j] = a[k] 186 | j++ 187 | } 188 | 189 | return a[:j] 190 | } 191 | 192 | // DeduplicateInt64 performs order preserving, in place deduplication of a int64 slice 193 | func DeduplicateInt64(a []int64) []int64 { 194 | if len(a) < 2 { 195 | return a 196 | } 197 | 198 | seen := make(map[int64]struct{}) 199 | 200 | j := 0 201 | for k := range a { 202 | if _, ok := seen[a[k]]; ok { 203 | continue 204 | } 205 | seen[a[k]] = struct{}{} 206 | a[j] = a[k] 207 | j++ 208 | } 209 | 210 | return a[:j] 211 | } 212 | 213 | // DeduplicateInt8 performs order preserving, in place deduplication of a int8 slice 214 | func DeduplicateInt8(a []int8) []int8 { 215 | if len(a) < 2 { 216 | return a 217 | } 218 | 219 | seen := make(map[int8]struct{}) 220 | 221 | j := 0 222 | for k := range a { 223 | if _, ok := seen[a[k]]; ok { 224 | continue 225 | } 226 | seen[a[k]] = struct{}{} 227 | a[j] = a[k] 228 | j++ 229 | } 230 | 231 | return a[:j] 232 | } 233 | 234 | // DeduplicateRune performs order preserving, in place deduplication of a rune slice 235 | func DeduplicateRune(a []rune) []rune { 236 | if len(a) < 2 { 237 | return a 238 | } 239 | 240 | seen := make(map[rune]struct{}) 241 | 242 | j := 0 243 | for k := range a { 244 | if _, ok := seen[a[k]]; ok { 245 | continue 246 | } 247 | seen[a[k]] = struct{}{} 248 | a[j] = a[k] 249 | j++ 250 | } 251 | 252 | return a[:j] 253 | } 254 | 255 | // DeduplicateString performs order preserving, in place deduplication of a string slice 256 | func DeduplicateString(a []string) []string { 257 | if len(a) < 2 { 258 | return a 259 | } 260 | 261 | seen := make(map[string]struct{}) 262 | 263 | j := 0 264 | for k := range a { 265 | if _, ok := seen[a[k]]; ok { 266 | continue 267 | } 268 | seen[a[k]] = struct{}{} 269 | a[j] = a[k] 270 | j++ 271 | } 272 | 273 | return a[:j] 274 | } 275 | 276 | // DeduplicateUint performs order preserving, in place deduplication of a uint slice 277 | func DeduplicateUint(a []uint) []uint { 278 | if len(a) < 2 { 279 | return a 280 | } 281 | 282 | seen := make(map[uint]struct{}) 283 | 284 | j := 0 285 | for k := range a { 286 | if _, ok := seen[a[k]]; ok { 287 | continue 288 | } 289 | seen[a[k]] = struct{}{} 290 | a[j] = a[k] 291 | j++ 292 | } 293 | 294 | return a[:j] 295 | } 296 | 297 | // DeduplicateUint16 performs order preserving, in place deduplication of a uint16 slice 298 | func DeduplicateUint16(a []uint16) []uint16 { 299 | if len(a) < 2 { 300 | return a 301 | } 302 | 303 | seen := make(map[uint16]struct{}) 304 | 305 | j := 0 306 | for k := range a { 307 | if _, ok := seen[a[k]]; ok { 308 | continue 309 | } 310 | seen[a[k]] = struct{}{} 311 | a[j] = a[k] 312 | j++ 313 | } 314 | 315 | return a[:j] 316 | } 317 | 318 | // DeduplicateUint32 performs order preserving, in place deduplication of a uint32 slice 319 | func DeduplicateUint32(a []uint32) []uint32 { 320 | if len(a) < 2 { 321 | return a 322 | } 323 | 324 | seen := make(map[uint32]struct{}) 325 | 326 | j := 0 327 | for k := range a { 328 | if _, ok := seen[a[k]]; ok { 329 | continue 330 | } 331 | seen[a[k]] = struct{}{} 332 | a[j] = a[k] 333 | j++ 334 | } 335 | 336 | return a[:j] 337 | } 338 | 339 | // DeduplicateUint64 performs order preserving, in place deduplication of a uint64 slice 340 | func DeduplicateUint64(a []uint64) []uint64 { 341 | if len(a) < 2 { 342 | return a 343 | } 344 | 345 | seen := make(map[uint64]struct{}) 346 | 347 | j := 0 348 | for k := range a { 349 | if _, ok := seen[a[k]]; ok { 350 | continue 351 | } 352 | seen[a[k]] = struct{}{} 353 | a[j] = a[k] 354 | j++ 355 | } 356 | 357 | return a[:j] 358 | } 359 | 360 | // DeduplicateUint8 performs order preserving, in place deduplication of a uint8 slice 361 | func DeduplicateUint8(a []uint8) []uint8 { 362 | if len(a) < 2 { 363 | return a 364 | } 365 | 366 | seen := make(map[uint8]struct{}) 367 | 368 | j := 0 369 | for k := range a { 370 | if _, ok := seen[a[k]]; ok { 371 | continue 372 | } 373 | seen[a[k]] = struct{}{} 374 | a[j] = a[k] 375 | j++ 376 | } 377 | 378 | return a[:j] 379 | } 380 | 381 | // DeduplicateUintptr performs order preserving, in place deduplication of a uintptr slice 382 | func DeduplicateUintptr(a []uintptr) []uintptr { 383 | if len(a) < 2 { 384 | return a 385 | } 386 | 387 | seen := make(map[uintptr]struct{}) 388 | 389 | j := 0 390 | for k := range a { 391 | if _, ok := seen[a[k]]; ok { 392 | continue 393 | } 394 | seen[a[k]] = struct{}{} 395 | a[j] = a[k] 396 | j++ 397 | } 398 | 399 | return a[:j] 400 | } 401 | -------------------------------------------------------------------------------- /deduplicate_test.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestDeduplicateBool(t *testing.T) { 10 | type args struct { 11 | a []bool 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []bool 17 | }{ 18 | { 19 | name: "nil slice", 20 | args: args{ 21 | a: nil, 22 | }, 23 | want: nil, 24 | }, 25 | { 26 | name: "empty slice", 27 | args: args{ 28 | a: []bool{}, 29 | }, 30 | want: []bool{}, 31 | }, 32 | { 33 | name: "non empty slice", 34 | args: args{ 35 | a: []bool{true, false, true, false}, 36 | }, 37 | want: []bool{true, false}, 38 | }, 39 | } 40 | for _, tt := range tests { 41 | t.Run(tt.name, func(t *testing.T) { 42 | if got := DeduplicateBool(tt.args.a); !reflect.DeepEqual(got, tt.want) { 43 | t.Errorf("DeduplicateBool() = %v, want %v", got, tt.want) 44 | } 45 | }) 46 | } 47 | } 48 | 49 | func TestDeduplicateByte(t *testing.T) { 50 | type args struct { 51 | a []byte 52 | } 53 | tests := []struct { 54 | name string 55 | args args 56 | want []byte 57 | }{ 58 | { 59 | name: "nil slice", 60 | args: args{ 61 | a: nil, 62 | }, 63 | want: nil, 64 | }, 65 | { 66 | name: "empty slice", 67 | args: args{ 68 | a: []byte{}, 69 | }, 70 | want: []byte{}, 71 | }, 72 | { 73 | name: "non empty slice", 74 | args: args{ 75 | a: []byte{1, 2, 3, 3, 2, 5, 3}, 76 | }, 77 | want: []byte{1, 2, 3, 5}, 78 | }, 79 | } 80 | for _, tt := range tests { 81 | t.Run(tt.name, func(t *testing.T) { 82 | if got := DeduplicateByte(tt.args.a); !reflect.DeepEqual(got, tt.want) { 83 | t.Errorf("DeduplicateByte() = %v, want %v", got, tt.want) 84 | } 85 | }) 86 | } 87 | } 88 | 89 | func TestDeduplicateComplex128(t *testing.T) { 90 | type args struct { 91 | a []complex128 92 | } 93 | tests := []struct { 94 | name string 95 | args args 96 | want []complex128 97 | }{ 98 | { 99 | name: "nil slice", 100 | args: args{ 101 | a: nil, 102 | }, 103 | want: nil, 104 | }, 105 | { 106 | name: "empty slice", 107 | args: args{ 108 | a: []complex128{}, 109 | }, 110 | want: []complex128{}, 111 | }, 112 | { 113 | name: "non empty slice", 114 | args: args{ 115 | a: []complex128{complex(1, 1), complex(2, 2), complex(3, 3), complex(3, 3), complex(4, 4), complex(5, 5), complex(3, 3)}, 116 | }, 117 | want: []complex128{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4), complex(5, 5)}, 118 | }, 119 | } 120 | for _, tt := range tests { 121 | t.Run(tt.name, func(t *testing.T) { 122 | if got := DeduplicateComplex128(tt.args.a); !reflect.DeepEqual(got, tt.want) { 123 | t.Errorf("DeduplicateComplex128() = %v, want %v", got, tt.want) 124 | } 125 | }) 126 | } 127 | } 128 | 129 | func TestDeduplicateComplex64(t *testing.T) { 130 | type args struct { 131 | a []complex64 132 | } 133 | tests := []struct { 134 | name string 135 | args args 136 | want []complex64 137 | }{ 138 | { 139 | name: "nil slice", 140 | args: args{ 141 | a: nil, 142 | }, 143 | want: nil, 144 | }, 145 | { 146 | name: "empty slice", 147 | args: args{ 148 | a: []complex64{}, 149 | }, 150 | want: []complex64{}, 151 | }, 152 | { 153 | name: "non empty slice", 154 | args: args{ 155 | a: []complex64{complex(1, 1), complex(2, 2), complex(3, 3), complex(3, 3), complex(4, 4), complex(5, 5), complex(3, 3)}, 156 | }, 157 | want: []complex64{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4), complex(5, 5)}, 158 | }, 159 | } 160 | for _, tt := range tests { 161 | t.Run(tt.name, func(t *testing.T) { 162 | if got := DeduplicateComplex64(tt.args.a); !reflect.DeepEqual(got, tt.want) { 163 | t.Errorf("DeduplicateComplex64() = %v, want %v", got, tt.want) 164 | } 165 | }) 166 | } 167 | } 168 | 169 | func TestDeduplicateFloat32(t *testing.T) { 170 | type args struct { 171 | a []float32 172 | } 173 | tests := []struct { 174 | name string 175 | args args 176 | want []float32 177 | }{ 178 | { 179 | name: "nil slice", 180 | args: args{ 181 | a: nil, 182 | }, 183 | want: nil, 184 | }, 185 | { 186 | name: "empty slice", 187 | args: args{ 188 | a: []float32{}, 189 | }, 190 | want: []float32{}, 191 | }, 192 | { 193 | name: "non empty slice", 194 | args: args{ 195 | a: []float32{1.1, 2.2, 3.3, 3.3, 2.2, 5.5, 3.3}, 196 | }, 197 | want: []float32{1.1, 2.2, 3.3, 5.5}, 198 | }, 199 | } 200 | for _, tt := range tests { 201 | t.Run(tt.name, func(t *testing.T) { 202 | if got := DeduplicateFloat32(tt.args.a); !reflect.DeepEqual(got, tt.want) { 203 | t.Errorf("DeduplicateFloat32() = %v, want %v", got, tt.want) 204 | } 205 | }) 206 | } 207 | } 208 | 209 | func TestDeduplicateFloat64(t *testing.T) { 210 | type args struct { 211 | a []float64 212 | } 213 | tests := []struct { 214 | name string 215 | args args 216 | want []float64 217 | }{ 218 | { 219 | name: "nil slice", 220 | args: args{ 221 | a: nil, 222 | }, 223 | want: nil, 224 | }, 225 | { 226 | name: "empty slice", 227 | args: args{ 228 | a: []float64{}, 229 | }, 230 | want: []float64{}, 231 | }, 232 | { 233 | name: "non empty slice", 234 | args: args{ 235 | a: []float64{1.1, 2.2, 3.3, 3.3, 2.2, 5.5, 3.3}, 236 | }, 237 | want: []float64{1.1, 2.2, 3.3, 5.5}, 238 | }, 239 | } 240 | for _, tt := range tests { 241 | t.Run(tt.name, func(t *testing.T) { 242 | if got := DeduplicateFloat64(tt.args.a); !reflect.DeepEqual(got, tt.want) { 243 | t.Errorf("DeduplicateFloat64() = %v, want %v", got, tt.want) 244 | } 245 | }) 246 | } 247 | } 248 | 249 | func TestDeduplicateInt(t *testing.T) { 250 | type args struct { 251 | a []int 252 | } 253 | tests := []struct { 254 | name string 255 | args args 256 | want []int 257 | }{ 258 | { 259 | name: "nil slice", 260 | args: args{ 261 | a: nil, 262 | }, 263 | want: nil, 264 | }, 265 | { 266 | name: "empty slice", 267 | args: args{ 268 | a: []int{}, 269 | }, 270 | want: []int{}, 271 | }, 272 | { 273 | name: "non empty slice", 274 | args: args{ 275 | a: []int{1, 2, 3, 3, 2, 5, 3}, 276 | }, 277 | want: []int{1, 2, 3, 5}, 278 | }, 279 | } 280 | for _, tt := range tests { 281 | t.Run(tt.name, func(t *testing.T) { 282 | if got := DeduplicateInt(tt.args.a); !reflect.DeepEqual(got, tt.want) { 283 | t.Errorf("DeduplicateInt() = %v, want %v", got, tt.want) 284 | } 285 | }) 286 | } 287 | } 288 | 289 | func TestDeduplicateInt16(t *testing.T) { 290 | type args struct { 291 | a []int16 292 | } 293 | tests := []struct { 294 | name string 295 | args args 296 | want []int16 297 | }{ 298 | { 299 | name: "nil slice", 300 | args: args{ 301 | a: nil, 302 | }, 303 | want: nil, 304 | }, 305 | { 306 | name: "empty slice", 307 | args: args{ 308 | a: []int16{}, 309 | }, 310 | want: []int16{}, 311 | }, 312 | { 313 | name: "non empty slice", 314 | args: args{ 315 | a: []int16{1, 2, 3, 3, 2, 5, 3}, 316 | }, 317 | want: []int16{1, 2, 3, 5}, 318 | }, 319 | } 320 | for _, tt := range tests { 321 | t.Run(tt.name, func(t *testing.T) { 322 | if got := DeduplicateInt16(tt.args.a); !reflect.DeepEqual(got, tt.want) { 323 | t.Errorf("DeduplicateInt16() = %v, want %v", got, tt.want) 324 | } 325 | }) 326 | } 327 | } 328 | 329 | func TestDeduplicateInt32(t *testing.T) { 330 | type args struct { 331 | a []int32 332 | } 333 | tests := []struct { 334 | name string 335 | args args 336 | want []int32 337 | }{ 338 | { 339 | name: "nil slice", 340 | args: args{ 341 | a: nil, 342 | }, 343 | want: nil, 344 | }, 345 | { 346 | name: "empty slice", 347 | args: args{ 348 | a: []int32{}, 349 | }, 350 | want: []int32{}, 351 | }, 352 | { 353 | name: "non empty slice", 354 | args: args{ 355 | a: []int32{1, 2, 3, 3, 2, 5, 3}, 356 | }, 357 | want: []int32{1, 2, 3, 5}, 358 | }, 359 | } 360 | for _, tt := range tests { 361 | t.Run(tt.name, func(t *testing.T) { 362 | if got := DeduplicateInt32(tt.args.a); !reflect.DeepEqual(got, tt.want) { 363 | t.Errorf("DeduplicateInt32() = %v, want %v", got, tt.want) 364 | } 365 | }) 366 | } 367 | } 368 | 369 | func TestDeduplicateInt64(t *testing.T) { 370 | type args struct { 371 | a []int64 372 | } 373 | tests := []struct { 374 | name string 375 | args args 376 | want []int64 377 | }{ 378 | { 379 | name: "nil slice", 380 | args: args{ 381 | a: nil, 382 | }, 383 | want: nil, 384 | }, 385 | { 386 | name: "empty slice", 387 | args: args{ 388 | a: []int64{}, 389 | }, 390 | want: []int64{}, 391 | }, 392 | { 393 | name: "non empty slice", 394 | args: args{ 395 | a: []int64{1, 2, 3, 3, 2, 5, 3}, 396 | }, 397 | want: []int64{1, 2, 3, 5}, 398 | }, 399 | } 400 | for _, tt := range tests { 401 | t.Run(tt.name, func(t *testing.T) { 402 | if got := DeduplicateInt64(tt.args.a); !reflect.DeepEqual(got, tt.want) { 403 | t.Errorf("DeduplicateInt64() = %v, want %v", got, tt.want) 404 | } 405 | }) 406 | } 407 | } 408 | 409 | func TestDeduplicateInt8(t *testing.T) { 410 | type args struct { 411 | a []int8 412 | } 413 | tests := []struct { 414 | name string 415 | args args 416 | want []int8 417 | }{ 418 | { 419 | name: "nil slice", 420 | args: args{ 421 | a: nil, 422 | }, 423 | want: nil, 424 | }, 425 | { 426 | name: "empty slice", 427 | args: args{ 428 | a: []int8{}, 429 | }, 430 | want: []int8{}, 431 | }, 432 | { 433 | name: "non empty slice", 434 | args: args{ 435 | a: []int8{1, 2, 3, 3, 2, 5, 3}, 436 | }, 437 | want: []int8{1, 2, 3, 5}, 438 | }, 439 | } 440 | for _, tt := range tests { 441 | t.Run(tt.name, func(t *testing.T) { 442 | if got := DeduplicateInt8(tt.args.a); !reflect.DeepEqual(got, tt.want) { 443 | t.Errorf("DeduplicateInt8() = %v, want %v", got, tt.want) 444 | } 445 | }) 446 | } 447 | } 448 | 449 | func TestDeduplicateRune(t *testing.T) { 450 | type args struct { 451 | a []rune 452 | } 453 | tests := []struct { 454 | name string 455 | args args 456 | want []rune 457 | }{ 458 | { 459 | name: "nil slice", 460 | args: args{ 461 | a: nil, 462 | }, 463 | want: nil, 464 | }, 465 | { 466 | name: "empty slice", 467 | args: args{ 468 | a: []rune{}, 469 | }, 470 | want: []rune{}, 471 | }, 472 | { 473 | name: "non empty slice", 474 | args: args{ 475 | a: []rune{1, 2, 3, 3, 2, 5, 3}, 476 | }, 477 | want: []rune{1, 2, 3, 5}, 478 | }, 479 | } 480 | for _, tt := range tests { 481 | t.Run(tt.name, func(t *testing.T) { 482 | if got := DeduplicateRune(tt.args.a); !reflect.DeepEqual(got, tt.want) { 483 | t.Errorf("DeduplicateRune() = %v, want %v", got, tt.want) 484 | } 485 | }) 486 | } 487 | } 488 | 489 | func TestDeduplicateString(t *testing.T) { 490 | type args struct { 491 | a []string 492 | } 493 | tests := []struct { 494 | name string 495 | args args 496 | want []string 497 | }{ 498 | { 499 | name: "nil slice", 500 | args: args{ 501 | a: nil, 502 | }, 503 | want: nil, 504 | }, 505 | { 506 | name: "empty slice", 507 | args: args{ 508 | a: []string{}, 509 | }, 510 | want: []string{}, 511 | }, 512 | { 513 | name: "non empty slice", 514 | args: args{ 515 | a: []string{"a", "b", "c", "c", "d", "e"}, 516 | }, 517 | want: []string{"a", "b", "c", "d", "e"}, 518 | }, 519 | } 520 | for _, tt := range tests { 521 | t.Run(tt.name, func(t *testing.T) { 522 | if got := DeduplicateString(tt.args.a); !reflect.DeepEqual(got, tt.want) { 523 | t.Errorf("DeduplicateString() = %v, want %v", got, tt.want) 524 | } 525 | }) 526 | } 527 | } 528 | 529 | func TestDeduplicateUint(t *testing.T) { 530 | type args struct { 531 | a []uint 532 | } 533 | tests := []struct { 534 | name string 535 | args args 536 | want []uint 537 | }{ 538 | { 539 | name: "nil slice", 540 | args: args{ 541 | a: nil, 542 | }, 543 | want: nil, 544 | }, 545 | { 546 | name: "empty slice", 547 | args: args{ 548 | a: []uint{}, 549 | }, 550 | want: []uint{}, 551 | }, 552 | { 553 | name: "non empty slice", 554 | args: args{ 555 | a: []uint{1, 2, 3, 3, 2, 5, 3}, 556 | }, 557 | want: []uint{1, 2, 3, 5}, 558 | }, 559 | } 560 | for _, tt := range tests { 561 | t.Run(tt.name, func(t *testing.T) { 562 | if got := DeduplicateUint(tt.args.a); !reflect.DeepEqual(got, tt.want) { 563 | t.Errorf("DeduplicateUint() = %v, want %v", got, tt.want) 564 | } 565 | }) 566 | } 567 | } 568 | 569 | func TestDeduplicateUint16(t *testing.T) { 570 | type args struct { 571 | a []uint16 572 | } 573 | tests := []struct { 574 | name string 575 | args args 576 | want []uint16 577 | }{ 578 | { 579 | name: "nil slice", 580 | args: args{ 581 | a: nil, 582 | }, 583 | want: nil, 584 | }, 585 | { 586 | name: "empty slice", 587 | args: args{ 588 | a: []uint16{}, 589 | }, 590 | want: []uint16{}, 591 | }, 592 | { 593 | name: "non empty slice", 594 | args: args{ 595 | a: []uint16{1, 2, 3, 3, 2, 5, 3}, 596 | }, 597 | want: []uint16{1, 2, 3, 5}, 598 | }, 599 | } 600 | for _, tt := range tests { 601 | t.Run(tt.name, func(t *testing.T) { 602 | if got := DeduplicateUint16(tt.args.a); !reflect.DeepEqual(got, tt.want) { 603 | t.Errorf("DeduplicateUint16() = %v, want %v", got, tt.want) 604 | } 605 | }) 606 | } 607 | } 608 | 609 | func TestDeduplicateUint32(t *testing.T) { 610 | type args struct { 611 | a []uint32 612 | } 613 | tests := []struct { 614 | name string 615 | args args 616 | want []uint32 617 | }{ 618 | { 619 | name: "nil slice", 620 | args: args{ 621 | a: nil, 622 | }, 623 | want: nil, 624 | }, 625 | { 626 | name: "empty slice", 627 | args: args{ 628 | a: []uint32{}, 629 | }, 630 | want: []uint32{}, 631 | }, 632 | { 633 | name: "non empty slice", 634 | args: args{ 635 | a: []uint32{1, 2, 3, 3, 2, 5, 3}, 636 | }, 637 | want: []uint32{1, 2, 3, 5}, 638 | }, 639 | } 640 | for _, tt := range tests { 641 | t.Run(tt.name, func(t *testing.T) { 642 | if got := DeduplicateUint32(tt.args.a); !reflect.DeepEqual(got, tt.want) { 643 | t.Errorf("DeduplicateUint32() = %v, want %v", got, tt.want) 644 | } 645 | }) 646 | } 647 | } 648 | 649 | func TestDeduplicateUint64(t *testing.T) { 650 | type args struct { 651 | a []uint64 652 | } 653 | tests := []struct { 654 | name string 655 | args args 656 | want []uint64 657 | }{ 658 | { 659 | name: "nil slice", 660 | args: args{ 661 | a: nil, 662 | }, 663 | want: nil, 664 | }, 665 | { 666 | name: "empty slice", 667 | args: args{ 668 | a: []uint64{}, 669 | }, 670 | want: []uint64{}, 671 | }, 672 | { 673 | name: "non empty slice", 674 | args: args{ 675 | a: []uint64{1, 2, 3, 3, 2, 5, 3}, 676 | }, 677 | want: []uint64{1, 2, 3, 5}, 678 | }, 679 | } 680 | for _, tt := range tests { 681 | t.Run(tt.name, func(t *testing.T) { 682 | if got := DeduplicateUint64(tt.args.a); !reflect.DeepEqual(got, tt.want) { 683 | t.Errorf("DeduplicateUint64() = %v, want %v", got, tt.want) 684 | } 685 | }) 686 | } 687 | } 688 | 689 | func TestDeduplicateUint8(t *testing.T) { 690 | type args struct { 691 | a []uint8 692 | } 693 | tests := []struct { 694 | name string 695 | args args 696 | want []uint8 697 | }{ 698 | { 699 | name: "nil slice", 700 | args: args{ 701 | a: nil, 702 | }, 703 | want: nil, 704 | }, 705 | { 706 | name: "empty slice", 707 | args: args{ 708 | a: []uint8{}, 709 | }, 710 | want: []uint8{}, 711 | }, 712 | { 713 | name: "non empty slice", 714 | args: args{ 715 | a: []uint8{1, 2, 3, 3, 2, 5, 3}, 716 | }, 717 | want: []uint8{1, 2, 3, 5}, 718 | }, 719 | } 720 | for _, tt := range tests { 721 | t.Run(tt.name, func(t *testing.T) { 722 | if got := DeduplicateUint8(tt.args.a); !reflect.DeepEqual(got, tt.want) { 723 | t.Errorf("DeduplicateUint8() = %v, want %v", got, tt.want) 724 | } 725 | }) 726 | } 727 | } 728 | 729 | func TestDeduplicateUintptr(t *testing.T) { 730 | type args struct { 731 | a []uintptr 732 | } 733 | tests := []struct { 734 | name string 735 | args args 736 | want []uintptr 737 | }{ 738 | { 739 | name: "nil slice", 740 | args: args{ 741 | a: nil, 742 | }, 743 | want: nil, 744 | }, 745 | { 746 | name: "empty slice", 747 | args: args{ 748 | a: []uintptr{}, 749 | }, 750 | want: []uintptr{}, 751 | }, 752 | { 753 | name: "non empty slice", 754 | args: args{ 755 | a: []uintptr{1, 2, 3, 3, 2, 5, 3}, 756 | }, 757 | want: []uintptr{1, 2, 3, 5}, 758 | }, 759 | } 760 | for _, tt := range tests { 761 | t.Run(tt.name, func(t *testing.T) { 762 | if got := DeduplicateUintptr(tt.args.a); !reflect.DeepEqual(got, tt.want) { 763 | t.Errorf("DeduplicateUintptr() = %v, want %v", got, tt.want) 764 | } 765 | }) 766 | } 767 | } 768 | 769 | func ExampleDeduplicateInt() { 770 | a := []int{1, 2, 3, 2, 5, 3} 771 | a = DeduplicateInt(a) 772 | fmt.Printf("%v", a) 773 | // Output: [1 2 3 5] 774 | } 775 | -------------------------------------------------------------------------------- /delete.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import "errors" 4 | 5 | // DeleteBool removes an element at a specific index of a bool slice. 6 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 7 | func DeleteBool(a []bool, i int) ([]bool, error) { 8 | if len(a) == 0 { 9 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 10 | } 11 | if i < 0 || i > len(a)-1 { 12 | return nil, errors.New("Index out of bounds") 13 | } 14 | 15 | return append(a[:i], a[i+1:]...), nil 16 | } 17 | 18 | // DeleteByte removes an element at a specific index of a byte slice. 19 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 20 | func DeleteByte(a []byte, i int) ([]byte, error) { 21 | if len(a) == 0 { 22 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 23 | } 24 | if i < 0 || i > len(a)-1 { 25 | return nil, errors.New("Index out of bounds") 26 | } 27 | 28 | return append(a[:i], a[i+1:]...), nil 29 | } 30 | 31 | // DeleteComplex128 removes an element at a specific index of a complex128 slice. 32 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 33 | func DeleteComplex128(a []complex128, i int) ([]complex128, error) { 34 | if len(a) == 0 { 35 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 36 | } 37 | if i < 0 || i > len(a)-1 { 38 | return nil, errors.New("Index out of bounds") 39 | } 40 | 41 | return append(a[:i], a[i+1:]...), nil 42 | } 43 | 44 | // DeleteComplex64 removes an element at a specific index of a complex64 slice. 45 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 46 | func DeleteComplex64(a []complex64, i int) ([]complex64, error) { 47 | if len(a) == 0 { 48 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 49 | } 50 | if i < 0 || i > len(a)-1 { 51 | return nil, errors.New("Index out of bounds") 52 | } 53 | 54 | return append(a[:i], a[i+1:]...), nil 55 | } 56 | 57 | // DeleteFloat32 removes an element at a specific index of a float32 slice. 58 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 59 | func DeleteFloat32(a []float32, i int) ([]float32, error) { 60 | if len(a) == 0 { 61 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 62 | } 63 | if i < 0 || i > len(a)-1 { 64 | return nil, errors.New("Index out of bounds") 65 | } 66 | 67 | return append(a[:i], a[i+1:]...), nil 68 | } 69 | 70 | // DeleteFloat64 removes an element at a specific index of a float64 slice. 71 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 72 | func DeleteFloat64(a []float64, i int) ([]float64, error) { 73 | if len(a) == 0 { 74 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 75 | } 76 | if i < 0 || i > len(a)-1 { 77 | return nil, errors.New("Index out of bounds") 78 | } 79 | 80 | return append(a[:i], a[i+1:]...), nil 81 | } 82 | 83 | // DeleteInt removes an element at a specific index of an int slice. 84 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 85 | func DeleteInt(a []int, i int) ([]int, error) { 86 | if len(a) == 0 { 87 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 88 | } 89 | if i < 0 || i > len(a)-1 { 90 | return nil, errors.New("Index out of bounds") 91 | } 92 | 93 | return append(a[:i], a[i+1:]...), nil 94 | } 95 | 96 | // DeleteInt16 removes an element at a specific index of an int16 slice. 97 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 98 | func DeleteInt16(a []int16, i int) ([]int16, error) { 99 | if len(a) == 0 { 100 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 101 | } 102 | if i < 0 || i > len(a)-1 { 103 | return nil, errors.New("Index out of bounds") 104 | } 105 | 106 | return append(a[:i], a[i+1:]...), nil 107 | } 108 | 109 | // DeleteInt32 removes an element at a specific index of an int32 slice. 110 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 111 | func DeleteInt32(a []int32, i int) ([]int32, error) { 112 | if len(a) == 0 { 113 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 114 | } 115 | if i < 0 || i > len(a)-1 { 116 | return nil, errors.New("Index out of bounds") 117 | } 118 | 119 | return append(a[:i], a[i+1:]...), nil 120 | } 121 | 122 | // DeleteInt64 removes an element at a specific index of an int64 slice. 123 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 124 | func DeleteInt64(a []int64, i int) ([]int64, error) { 125 | if len(a) == 0 { 126 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 127 | } 128 | if i < 0 || i > len(a)-1 { 129 | return nil, errors.New("Index out of bounds") 130 | } 131 | 132 | return append(a[:i], a[i+1:]...), nil 133 | } 134 | 135 | // DeleteInt8 removes an element at a specific index of an int8 slice. 136 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 137 | func DeleteInt8(a []int8, i int) ([]int8, error) { 138 | if len(a) == 0 { 139 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 140 | } 141 | if i < 0 || i > len(a)-1 { 142 | return nil, errors.New("Index out of bounds") 143 | } 144 | 145 | return append(a[:i], a[i+1:]...), nil 146 | } 147 | 148 | // DeleteRune removes an element at a specific index of a rune slice. 149 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 150 | func DeleteRune(a []rune, i int) ([]rune, error) { 151 | if len(a) == 0 { 152 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 153 | } 154 | if i < 0 || i > len(a)-1 { 155 | return nil, errors.New("Index out of bounds") 156 | } 157 | 158 | return append(a[:i], a[i+1:]...), nil 159 | } 160 | 161 | // DeleteString removes an element at a specific index of a string slice. 162 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 163 | func DeleteString(a []string, i int) ([]string, error) { 164 | if len(a) == 0 { 165 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 166 | } 167 | if i < 0 || i > len(a)-1 { 168 | return nil, errors.New("Index out of bounds") 169 | } 170 | 171 | return append(a[:i], a[i+1:]...), nil 172 | } 173 | 174 | // DeleteUint removes an element at a specific index of a uint slice. 175 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 176 | func DeleteUint(a []uint, i int) ([]uint, error) { 177 | if len(a) == 0 { 178 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 179 | } 180 | if i < 0 || i > len(a)-1 { 181 | return nil, errors.New("Index out of bounds") 182 | } 183 | 184 | return append(a[:i], a[i+1:]...), nil 185 | } 186 | 187 | // DeleteUint16 removes an element at a specific index of a uint16 slice. 188 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 189 | func DeleteUint16(a []uint16, i int) ([]uint16, error) { 190 | if len(a) == 0 { 191 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 192 | } 193 | if i < 0 || i > len(a)-1 { 194 | return nil, errors.New("Index out of bounds") 195 | } 196 | 197 | return append(a[:i], a[i+1:]...), nil 198 | } 199 | 200 | // DeleteUint32 removes an element at a specific index of a uint32 slice. 201 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 202 | func DeleteUint32(a []uint32, i int) ([]uint32, error) { 203 | if len(a) == 0 { 204 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 205 | } 206 | if i < 0 || i > len(a)-1 { 207 | return nil, errors.New("Index out of bounds") 208 | } 209 | 210 | return append(a[:i], a[i+1:]...), nil 211 | } 212 | 213 | // DeleteUint64 removes an element at a specific index of a uint64 slice. 214 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 215 | func DeleteUint64(a []uint64, i int) ([]uint64, error) { 216 | if len(a) == 0 { 217 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 218 | } 219 | if i < 0 || i > len(a)-1 { 220 | return nil, errors.New("Index out of bounds") 221 | } 222 | 223 | return append(a[:i], a[i+1:]...), nil 224 | } 225 | 226 | // DeleteUint8 removes an element at a specific index of a uint8 slice. 227 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 228 | func DeleteUint8(a []uint8, i int) ([]uint8, error) { 229 | if len(a) == 0 { 230 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 231 | } 232 | if i < 0 || i > len(a)-1 { 233 | return nil, errors.New("Index out of bounds") 234 | } 235 | 236 | return append(a[:i], a[i+1:]...), nil 237 | } 238 | 239 | // DeleteUintptr removes an element at a specific index of a uintptr slice. 240 | // An error is return in case the index is out of bounds or if the slice is nil or empty. 241 | func DeleteUintptr(a []uintptr, i int) ([]uintptr, error) { 242 | if len(a) == 0 { 243 | return nil, errors.New("Cannot delete an element from a nil or empty slice") 244 | } 245 | if i < 0 || i > len(a)-1 { 246 | return nil, errors.New("Index out of bounds") 247 | } 248 | 249 | return append(a[:i], a[i+1:]...), nil 250 | } 251 | -------------------------------------------------------------------------------- /deleterange.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import "errors" 4 | 5 | // DeleteRangeBool deletes the elements between from and to index (inclusive) from a bool slice 6 | func DeleteRangeBool(a []bool, from, to int) ([]bool, error) { 7 | if len(a) == 0 { 8 | return nil, errors.New("Cannot delete from a nil or empty slice") 9 | } 10 | 11 | if from < 0 || from > len(a)-1 { 12 | return nil, errors.New("from index out of bounds") 13 | } 14 | 15 | if to < 0 || to > len(a)-1 { 16 | return nil, errors.New("to index out of bounds") 17 | } 18 | 19 | if from > to { 20 | return nil, errors.New("from index must be less or equal to to index") 21 | } 22 | 23 | return append(a[:from], a[to+1:]...), nil 24 | } 25 | 26 | // DeleteRangeByte deletes the elements between from and to index (inclusive) from a byte slice 27 | func DeleteRangeByte(a []byte, from, to int) ([]byte, error) { 28 | if len(a) == 0 { 29 | return nil, errors.New("Cannot delete from a nil or empty slice") 30 | } 31 | 32 | if from < 0 || from > len(a)-1 { 33 | return nil, errors.New("from index out of bounds") 34 | } 35 | 36 | if to < 0 || to > len(a)-1 { 37 | return nil, errors.New("to index out of bounds") 38 | } 39 | 40 | if from > to { 41 | return nil, errors.New("from index must be less or equal to to index") 42 | } 43 | 44 | return append(a[:from], a[to+1:]...), nil 45 | } 46 | 47 | // DeleteRangeComplex128 deletes the elements between from and to index (inclusive) from a complex128 slice 48 | func DeleteRangeComplex128(a []complex128, from, to int) ([]complex128, error) { 49 | if len(a) == 0 { 50 | return nil, errors.New("Cannot delete from a nil or empty slice") 51 | } 52 | 53 | if from < 0 || from > len(a)-1 { 54 | return nil, errors.New("from index out of bounds") 55 | } 56 | 57 | if to < 0 || to > len(a)-1 { 58 | return nil, errors.New("to index out of bounds") 59 | } 60 | 61 | if from > to { 62 | return nil, errors.New("from index must be less or equal to to index") 63 | } 64 | 65 | return append(a[:from], a[to+1:]...), nil 66 | } 67 | 68 | // DeleteRangeComplex64 deletes the elements between from and to index (inclusive) from a complex64 slice 69 | func DeleteRangeComplex64(a []complex64, from, to int) ([]complex64, error) { 70 | if len(a) == 0 { 71 | return nil, errors.New("Cannot delete from a nil or empty slice") 72 | } 73 | 74 | if from < 0 || from > len(a)-1 { 75 | return nil, errors.New("from index out of bounds") 76 | } 77 | 78 | if to < 0 || to > len(a)-1 { 79 | return nil, errors.New("to index out of bounds") 80 | } 81 | 82 | if from > to { 83 | return nil, errors.New("from index must be less or equal to to index") 84 | } 85 | 86 | return append(a[:from], a[to+1:]...), nil 87 | } 88 | 89 | // DeleteRangeFloat32 deletes the elements between from and to index (inclusive) from a float32 slice 90 | func DeleteRangeFloat32(a []float32, from, to int) ([]float32, error) { 91 | if len(a) == 0 { 92 | return nil, errors.New("Cannot delete from a nil or empty slice") 93 | } 94 | 95 | if from < 0 || from > len(a)-1 { 96 | return nil, errors.New("from index out of bounds") 97 | } 98 | 99 | if to < 0 || to > len(a)-1 { 100 | return nil, errors.New("to index out of bounds") 101 | } 102 | 103 | if from > to { 104 | return nil, errors.New("from index must be less or equal to to index") 105 | } 106 | 107 | return append(a[:from], a[to+1:]...), nil 108 | } 109 | 110 | // DeleteRangeFloat64 deletes the elements between from and to index (inclusive) from a float64 slice 111 | func DeleteRangeFloat64(a []float64, from, to int) ([]float64, error) { 112 | if len(a) == 0 { 113 | return nil, errors.New("Cannot delete from a nil or empty slice") 114 | } 115 | 116 | if from < 0 || from > len(a)-1 { 117 | return nil, errors.New("from index out of bounds") 118 | } 119 | 120 | if to < 0 || to > len(a)-1 { 121 | return nil, errors.New("to index out of bounds") 122 | } 123 | 124 | if from > to { 125 | return nil, errors.New("from index must be less or equal to to index") 126 | } 127 | 128 | return append(a[:from], a[to+1:]...), nil 129 | } 130 | 131 | // DeleteRangeInt deletes the elements between from and to index (inclusive) from a int slice 132 | func DeleteRangeInt(a []int, from, to int) ([]int, error) { 133 | if len(a) == 0 { 134 | return nil, errors.New("Cannot delete from a nil or empty slice") 135 | } 136 | 137 | if from < 0 || from > len(a)-1 { 138 | return nil, errors.New("from index out of bounds") 139 | } 140 | 141 | if to < 0 || to > len(a)-1 { 142 | return nil, errors.New("to index out of bounds") 143 | } 144 | 145 | if from > to { 146 | return nil, errors.New("from index must be less or equal to to index") 147 | } 148 | 149 | return append(a[:from], a[to+1:]...), nil 150 | } 151 | 152 | // DeleteRangeInt16 deletes the elements between from and to index (inclusive) from a int16 slice 153 | func DeleteRangeInt16(a []int16, from, to int) ([]int16, error) { 154 | if len(a) == 0 { 155 | return nil, errors.New("Cannot delete from a nil or empty slice") 156 | } 157 | 158 | if from < 0 || from > len(a)-1 { 159 | return nil, errors.New("from index out of bounds") 160 | } 161 | 162 | if to < 0 || to > len(a)-1 { 163 | return nil, errors.New("to index out of bounds") 164 | } 165 | 166 | if from > to { 167 | return nil, errors.New("from index must be less or equal to to index") 168 | } 169 | 170 | return append(a[:from], a[to+1:]...), nil 171 | } 172 | 173 | // DeleteRangeInt32 deletes the elements between from and to index (inclusive) from a int32 slice 174 | func DeleteRangeInt32(a []int32, from, to int) ([]int32, error) { 175 | if len(a) == 0 { 176 | return nil, errors.New("Cannot delete from a nil or empty slice") 177 | } 178 | 179 | if from < 0 || from > len(a)-1 { 180 | return nil, errors.New("from index out of bounds") 181 | } 182 | 183 | if to < 0 || to > len(a)-1 { 184 | return nil, errors.New("to index out of bounds") 185 | } 186 | 187 | if from > to { 188 | return nil, errors.New("from index must be less or equal to to index") 189 | } 190 | 191 | return append(a[:from], a[to+1:]...), nil 192 | } 193 | 194 | // DeleteRangeInt64 deletes the elements between from and to index (inclusive) from a int64 slice 195 | func DeleteRangeInt64(a []int64, from, to int) ([]int64, error) { 196 | if len(a) == 0 { 197 | return nil, errors.New("Cannot delete from a nil or empty slice") 198 | } 199 | 200 | if from < 0 || from > len(a)-1 { 201 | return nil, errors.New("from index out of bounds") 202 | } 203 | 204 | if to < 0 || to > len(a)-1 { 205 | return nil, errors.New("to index out of bounds") 206 | } 207 | 208 | if from > to { 209 | return nil, errors.New("from index must be less or equal to to index") 210 | } 211 | 212 | return append(a[:from], a[to+1:]...), nil 213 | } 214 | 215 | // DeleteRangeInt8 deletes the elements between from and to index (inclusive) from a int8 slice 216 | func DeleteRangeInt8(a []int8, from, to int) ([]int8, error) { 217 | if len(a) == 0 { 218 | return nil, errors.New("Cannot delete from a nil or empty slice") 219 | } 220 | 221 | if from < 0 || from > len(a)-1 { 222 | return nil, errors.New("from index out of bounds") 223 | } 224 | 225 | if to < 0 || to > len(a)-1 { 226 | return nil, errors.New("to index out of bounds") 227 | } 228 | 229 | if from > to { 230 | return nil, errors.New("from index must be less or equal to to index") 231 | } 232 | 233 | return append(a[:from], a[to+1:]...), nil 234 | } 235 | 236 | // DeleteRangeRune deletes the elements between from and to index (inclusive) from a rune slice 237 | func DeleteRangeRune(a []rune, from, to int) ([]rune, error) { 238 | if len(a) == 0 { 239 | return nil, errors.New("Cannot delete from a nil or empty slice") 240 | } 241 | 242 | if from < 0 || from > len(a)-1 { 243 | return nil, errors.New("from index out of bounds") 244 | } 245 | 246 | if to < 0 || to > len(a)-1 { 247 | return nil, errors.New("to index out of bounds") 248 | } 249 | 250 | if from > to { 251 | return nil, errors.New("from index must be less or equal to to index") 252 | } 253 | 254 | return append(a[:from], a[to+1:]...), nil 255 | } 256 | 257 | // DeleteRangeString deletes the elements between from and to index (inclusive) from a string slice 258 | func DeleteRangeString(a []string, from, to int) ([]string, error) { 259 | if len(a) == 0 { 260 | return nil, errors.New("Cannot delete from a nil or empty slice") 261 | } 262 | 263 | if from < 0 || from > len(a)-1 { 264 | return nil, errors.New("from index out of bounds") 265 | } 266 | 267 | if to < 0 || to > len(a)-1 { 268 | return nil, errors.New("to index out of bounds") 269 | } 270 | 271 | if from > to { 272 | return nil, errors.New("from index must be less or equal to to index") 273 | } 274 | 275 | return append(a[:from], a[to+1:]...), nil 276 | } 277 | 278 | // DeleteRangeUint deletes the elements between from and to index (inclusive) from a uint slice 279 | func DeleteRangeUint(a []uint, from, to int) ([]uint, error) { 280 | if len(a) == 0 { 281 | return nil, errors.New("Cannot delete from a nil or empty slice") 282 | } 283 | 284 | if from < 0 || from > len(a)-1 { 285 | return nil, errors.New("from index out of bounds") 286 | } 287 | 288 | if to < 0 || to > len(a)-1 { 289 | return nil, errors.New("to index out of bounds") 290 | } 291 | 292 | if from > to { 293 | return nil, errors.New("from index must be less or equal to to index") 294 | } 295 | 296 | return append(a[:from], a[to+1:]...), nil 297 | } 298 | 299 | // DeleteRangeUint16 deletes the elements between from and to index (inclusive) from a uint16 slice 300 | func DeleteRangeUint16(a []uint16, from, to int) ([]uint16, error) { 301 | if len(a) == 0 { 302 | return nil, errors.New("Cannot delete from a nil or empty slice") 303 | } 304 | 305 | if from < 0 || from > len(a)-1 { 306 | return nil, errors.New("from index out of bounds") 307 | } 308 | 309 | if to < 0 || to > len(a)-1 { 310 | return nil, errors.New("to index out of bounds") 311 | } 312 | 313 | if from > to { 314 | return nil, errors.New("from index must be less or equal to to index") 315 | } 316 | 317 | return append(a[:from], a[to+1:]...), nil 318 | } 319 | 320 | // DeleteRangeUint32 deletes the elements between from and to index (inclusive) from a uint32 slice 321 | func DeleteRangeUint32(a []uint32, from, to int) ([]uint32, error) { 322 | if len(a) == 0 { 323 | return nil, errors.New("Cannot delete from a nil or empty slice") 324 | } 325 | 326 | if from < 0 || from > len(a)-1 { 327 | return nil, errors.New("from index out of bounds") 328 | } 329 | 330 | if to < 0 || to > len(a)-1 { 331 | return nil, errors.New("to index out of bounds") 332 | } 333 | 334 | if from > to { 335 | return nil, errors.New("from index must be less or equal to to index") 336 | } 337 | 338 | return append(a[:from], a[to+1:]...), nil 339 | } 340 | 341 | // DeleteRangeUint64 deletes the elements between from and to index (inclusive) from a uint64 slice 342 | func DeleteRangeUint64(a []uint64, from, to int) ([]uint64, error) { 343 | if len(a) == 0 { 344 | return nil, errors.New("Cannot delete from a nil or empty slice") 345 | } 346 | 347 | if from < 0 || from > len(a)-1 { 348 | return nil, errors.New("from index out of bounds") 349 | } 350 | 351 | if to < 0 || to > len(a)-1 { 352 | return nil, errors.New("to index out of bounds") 353 | } 354 | 355 | if from > to { 356 | return nil, errors.New("from index must be less or equal to to index") 357 | } 358 | 359 | return append(a[:from], a[to+1:]...), nil 360 | } 361 | 362 | // DeleteRangeUint8 deletes the elements between from and to index (inclusive) from a uint8 slice 363 | func DeleteRangeUint8(a []uint8, from, to int) ([]uint8, error) { 364 | if len(a) == 0 { 365 | return nil, errors.New("Cannot delete from a nil or empty slice") 366 | } 367 | 368 | if from < 0 || from > len(a)-1 { 369 | return nil, errors.New("from index out of bounds") 370 | } 371 | 372 | if to < 0 || to > len(a)-1 { 373 | return nil, errors.New("to index out of bounds") 374 | } 375 | 376 | if from > to { 377 | return nil, errors.New("from index must be less or equal to to index") 378 | } 379 | 380 | return append(a[:from], a[to+1:]...), nil 381 | } 382 | 383 | // DeleteRangeUintptr deletes the elements between from and to index (inclusive) from a uintptr slice 384 | func DeleteRangeUintptr(a []uintptr, from, to int) ([]uintptr, error) { 385 | if len(a) == 0 { 386 | return nil, errors.New("Cannot delete from a nil or empty slice") 387 | } 388 | 389 | if from < 0 || from > len(a)-1 { 390 | return nil, errors.New("from index out of bounds") 391 | } 392 | 393 | if to < 0 || to > len(a)-1 { 394 | return nil, errors.New("to index out of bounds") 395 | } 396 | 397 | if from > to { 398 | return nil, errors.New("from index must be less or equal to to index") 399 | } 400 | 401 | return append(a[:from], a[to+1:]...), nil 402 | } 403 | -------------------------------------------------------------------------------- /filter.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | // FilterBool performs in place filtering of a bool slice based on a predicate 4 | func FilterBool(a []bool, keep func(x bool) bool) []bool { 5 | if len(a) == 0 { 6 | return a 7 | } 8 | 9 | n := 0 10 | for _, v := range a { 11 | if keep(v) { 12 | a[n] = v 13 | n++ 14 | } 15 | } 16 | 17 | return a[:n] 18 | } 19 | 20 | // FilterByte performs in place filtering of a byte slice based on a predicate 21 | func FilterByte(a []byte, keep func(x byte) bool) []byte { 22 | if len(a) == 0 { 23 | return a 24 | } 25 | 26 | n := 0 27 | for _, v := range a { 28 | if keep(v) { 29 | a[n] = v 30 | n++ 31 | } 32 | } 33 | 34 | return a[:n] 35 | } 36 | 37 | // FilterComplex128 performs in place filtering of a complex128 slice based on a predicate 38 | func FilterComplex128(a []complex128, keep func(x complex128) bool) []complex128 { 39 | if len(a) == 0 { 40 | return a 41 | } 42 | 43 | n := 0 44 | for _, v := range a { 45 | if keep(v) { 46 | a[n] = v 47 | n++ 48 | } 49 | } 50 | 51 | return a[:n] 52 | } 53 | 54 | // FilterComplex64 performs in place filtering of a complex64 slice based on a predicate 55 | func FilterComplex64(a []complex64, keep func(x complex64) bool) []complex64 { 56 | if len(a) == 0 { 57 | return a 58 | } 59 | 60 | n := 0 61 | for _, v := range a { 62 | if keep(v) { 63 | a[n] = v 64 | n++ 65 | } 66 | } 67 | 68 | return a[:n] 69 | } 70 | 71 | // FilterFloat32 performs in place filtering of a float32 slice based on a predicate 72 | func FilterFloat32(a []float32, keep func(x float32) bool) []float32 { 73 | if len(a) == 0 { 74 | return a 75 | } 76 | 77 | n := 0 78 | for _, v := range a { 79 | if keep(v) { 80 | a[n] = v 81 | n++ 82 | } 83 | } 84 | 85 | return a[:n] 86 | } 87 | 88 | // FilterFloat64 performs in place filtering of a float64 slice based on a predicate 89 | func FilterFloat64(a []float64, keep func(x float64) bool) []float64 { 90 | if len(a) == 0 { 91 | return a 92 | } 93 | 94 | n := 0 95 | for _, v := range a { 96 | if keep(v) { 97 | a[n] = v 98 | n++ 99 | } 100 | } 101 | 102 | return a[:n] 103 | } 104 | 105 | // FilterInt performs in place filtering of an int slice based on a predicate 106 | func FilterInt(a []int, keep func(x int) bool) []int { 107 | if len(a) == 0 { 108 | return a 109 | } 110 | 111 | n := 0 112 | for _, v := range a { 113 | if keep(v) { 114 | a[n] = v 115 | n++ 116 | } 117 | } 118 | 119 | return a[:n] 120 | } 121 | 122 | // FilterInt16 performs in place filtering of an int16 slice based on a predicate 123 | func FilterInt16(a []int16, keep func(x int16) bool) []int16 { 124 | if len(a) == 0 { 125 | return a 126 | } 127 | 128 | n := 0 129 | for _, v := range a { 130 | if keep(v) { 131 | a[n] = v 132 | n++ 133 | } 134 | } 135 | 136 | return a[:n] 137 | } 138 | 139 | // FilterInt32 performs in place filtering of an int32 slice based on a predicate 140 | func FilterInt32(a []int32, keep func(x int32) bool) []int32 { 141 | if len(a) == 0 { 142 | return a 143 | } 144 | 145 | n := 0 146 | for _, v := range a { 147 | if keep(v) { 148 | a[n] = v 149 | n++ 150 | } 151 | } 152 | 153 | return a[:n] 154 | } 155 | 156 | // FilterInt64 performs in place filtering of an int64 slice based on a predicate 157 | func FilterInt64(a []int64, keep func(x int64) bool) []int64 { 158 | if len(a) == 0 { 159 | return a 160 | } 161 | 162 | n := 0 163 | for _, v := range a { 164 | if keep(v) { 165 | a[n] = v 166 | n++ 167 | } 168 | } 169 | 170 | return a[:n] 171 | } 172 | 173 | // FilterInt8 performs in place filtering of an int8 slice based on a predicate 174 | func FilterInt8(a []int8, keep func(x int8) bool) []int8 { 175 | if len(a) == 0 { 176 | return a 177 | } 178 | 179 | n := 0 180 | for _, v := range a { 181 | if keep(v) { 182 | a[n] = v 183 | n++ 184 | } 185 | } 186 | 187 | return a[:n] 188 | } 189 | 190 | // FilterRune performs in place filtering of a rune slice based on a predicate 191 | func FilterRune(a []rune, keep func(x rune) bool) []rune { 192 | if len(a) == 0 { 193 | return a 194 | } 195 | 196 | n := 0 197 | for _, v := range a { 198 | if keep(v) { 199 | a[n] = v 200 | n++ 201 | } 202 | } 203 | 204 | return a[:n] 205 | } 206 | 207 | // FilterString performs in place filtering of a string slice based on a predicate 208 | func FilterString(a []string, keep func(x string) bool) []string { 209 | if len(a) == 0 { 210 | return a 211 | } 212 | 213 | n := 0 214 | for _, v := range a { 215 | if keep(v) { 216 | a[n] = v 217 | n++ 218 | } 219 | } 220 | 221 | return a[:n] 222 | } 223 | 224 | // FilterUint performs in place filtering of a uint slice based on a predicate 225 | func FilterUint(a []uint, keep func(x uint) bool) []uint { 226 | if len(a) == 0 { 227 | return a 228 | } 229 | 230 | n := 0 231 | for _, v := range a { 232 | if keep(v) { 233 | a[n] = v 234 | n++ 235 | } 236 | } 237 | 238 | return a[:n] 239 | } 240 | 241 | // FilterUint16 performs in place filtering of a uint16 slice based on a predicate 242 | func FilterUint16(a []uint16, keep func(x uint16) bool) []uint16 { 243 | if len(a) == 0 { 244 | return a 245 | } 246 | 247 | n := 0 248 | for _, v := range a { 249 | if keep(v) { 250 | a[n] = v 251 | n++ 252 | } 253 | } 254 | 255 | return a[:n] 256 | } 257 | 258 | // FilterUint32 performs in place filtering of a uint32 slice based on a predicate 259 | func FilterUint32(a []uint32, keep func(x uint32) bool) []uint32 { 260 | if len(a) == 0 { 261 | return a 262 | } 263 | 264 | n := 0 265 | for _, v := range a { 266 | if keep(v) { 267 | a[n] = v 268 | n++ 269 | } 270 | } 271 | 272 | return a[:n] 273 | } 274 | 275 | // FilterUint64 performs in place filtering of a uint64 slice based on a predicate 276 | func FilterUint64(a []uint64, keep func(x uint64) bool) []uint64 { 277 | if len(a) == 0 { 278 | return a 279 | } 280 | 281 | n := 0 282 | for _, v := range a { 283 | if keep(v) { 284 | a[n] = v 285 | n++ 286 | } 287 | } 288 | 289 | return a[:n] 290 | } 291 | 292 | // FilterUint8 performs in place filtering of a uint8 slice based on a predicate 293 | func FilterUint8(a []uint8, keep func(x uint8) bool) []uint8 { 294 | if len(a) == 0 { 295 | return a 296 | } 297 | 298 | n := 0 299 | for _, v := range a { 300 | if keep(v) { 301 | a[n] = v 302 | n++ 303 | } 304 | } 305 | 306 | return a[:n] 307 | } 308 | 309 | // FilterUintptr performs in place filtering of a uintptr slice based on a predicate 310 | func FilterUintptr(a []uintptr, keep func(x uintptr) bool) []uintptr { 311 | if len(a) == 0 { 312 | return a 313 | } 314 | 315 | n := 0 316 | for _, v := range a { 317 | if keep(v) { 318 | a[n] = v 319 | n++ 320 | } 321 | } 322 | 323 | return a[:n] 324 | } 325 | -------------------------------------------------------------------------------- /filter_test.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestFilterBool(t *testing.T) { 10 | type args struct { 11 | a []bool 12 | keep func(x bool) bool 13 | } 14 | tests := []struct { 15 | name string 16 | args args 17 | want []bool 18 | }{ 19 | { 20 | name: "nil slice", 21 | args: args{ 22 | a: nil, 23 | keep: func(bool) bool { panic("not implemented") }, 24 | }, 25 | want: nil, 26 | }, 27 | { 28 | name: "empty slice", 29 | args: args{ 30 | a: []bool{}, 31 | keep: func(bool) bool { panic("not implemented") }, 32 | }, 33 | want: []bool{}, 34 | }, 35 | { 36 | name: "non empty slice", 37 | args: args{ 38 | a: []bool{true, false, true, false}, 39 | keep: func(x bool) bool { 40 | return x 41 | }, 42 | }, 43 | want: []bool{true, true}, 44 | }, 45 | } 46 | for _, tt := range tests { 47 | t.Run(tt.name, func(t *testing.T) { 48 | if got := FilterBool(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 49 | t.Errorf("FilterBool() = %v, want %v", got, tt.want) 50 | } 51 | }) 52 | } 53 | } 54 | 55 | func TestFilterByte(t *testing.T) { 56 | type args struct { 57 | a []byte 58 | keep func(x byte) bool 59 | } 60 | tests := []struct { 61 | name string 62 | args args 63 | want []byte 64 | }{ 65 | { 66 | name: "nil slice", 67 | args: args{ 68 | a: nil, 69 | keep: func(byte) bool { panic("not implemented") }, 70 | }, 71 | want: nil, 72 | }, 73 | { 74 | name: "empty slice", 75 | args: args{ 76 | a: []byte{}, 77 | keep: func(byte) bool { panic("not implemented") }, 78 | }, 79 | want: []byte{}, 80 | }, 81 | { 82 | name: "non empty slice", 83 | args: args{ 84 | a: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 85 | keep: func(x byte) bool { 86 | return x < 5 87 | }, 88 | }, 89 | want: []byte{1, 2, 3, 4}, 90 | }, 91 | } 92 | for _, tt := range tests { 93 | t.Run(tt.name, func(t *testing.T) { 94 | if got := FilterByte(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 95 | t.Errorf("FilterByte() = %v, want %v", got, tt.want) 96 | } 97 | }) 98 | } 99 | } 100 | 101 | func TestFilterComplex128(t *testing.T) { 102 | type args struct { 103 | a []complex128 104 | keep func(x complex128) bool 105 | } 106 | tests := []struct { 107 | name string 108 | args args 109 | want []complex128 110 | }{ 111 | { 112 | name: "nil slice", 113 | args: args{ 114 | a: nil, 115 | keep: func(complex128) bool { panic("not implemented") }, 116 | }, 117 | want: nil, 118 | }, 119 | { 120 | name: "empty slice", 121 | args: args{ 122 | a: []complex128{}, 123 | keep: func(complex128) bool { panic("not implemented") }, 124 | }, 125 | want: []complex128{}, 126 | }, 127 | { 128 | name: "non empty slice", 129 | args: args{ 130 | a: []complex128{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4)}, 131 | keep: func(x complex128) bool { 132 | return real(x) < 3 133 | }, 134 | }, 135 | want: []complex128{complex(1, 1), complex(2, 2)}, 136 | }, 137 | } 138 | for _, tt := range tests { 139 | t.Run(tt.name, func(t *testing.T) { 140 | if got := FilterComplex128(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 141 | t.Errorf("FilterComplex128() = %v, want %v", got, tt.want) 142 | } 143 | }) 144 | } 145 | } 146 | 147 | func TestFilterComplex64(t *testing.T) { 148 | type args struct { 149 | a []complex64 150 | keep func(x complex64) bool 151 | } 152 | tests := []struct { 153 | name string 154 | args args 155 | want []complex64 156 | }{ 157 | { 158 | name: "nil slice", 159 | args: args{ 160 | a: nil, 161 | keep: func(complex64) bool { panic("not implemented") }, 162 | }, 163 | want: nil, 164 | }, 165 | { 166 | name: "empty slice", 167 | args: args{ 168 | a: []complex64{}, 169 | keep: func(complex64) bool { panic("not implemented") }, 170 | }, 171 | want: []complex64{}, 172 | }, 173 | { 174 | name: "non empty slice", 175 | args: args{ 176 | a: []complex64{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4)}, 177 | keep: func(x complex64) bool { 178 | return real(x) < 3 179 | }, 180 | }, 181 | want: []complex64{complex(1, 1), complex(2, 2)}, 182 | }, 183 | } 184 | for _, tt := range tests { 185 | t.Run(tt.name, func(t *testing.T) { 186 | if got := FilterComplex64(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 187 | t.Errorf("FilterComplex64() = %v, want %v", got, tt.want) 188 | } 189 | }) 190 | } 191 | } 192 | 193 | func TestFilterFloat32(t *testing.T) { 194 | type args struct { 195 | a []float32 196 | keep func(x float32) bool 197 | } 198 | tests := []struct { 199 | name string 200 | args args 201 | want []float32 202 | }{ 203 | { 204 | name: "nil slice", 205 | args: args{ 206 | a: nil, 207 | keep: func(float32) bool { panic("not implemented") }, 208 | }, 209 | want: nil, 210 | }, 211 | { 212 | name: "empty slice", 213 | args: args{ 214 | a: []float32{}, 215 | keep: func(float32) bool { panic("not implemented") }, 216 | }, 217 | want: []float32{}, 218 | }, 219 | { 220 | name: "non empty slice", 221 | args: args{ 222 | a: []float32{1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9}, 223 | keep: func(x float32) bool { 224 | return x < 5.5 225 | }, 226 | }, 227 | want: []float32{1.1, 2.2, 3.3, 4.4}, 228 | }, 229 | } 230 | for _, tt := range tests { 231 | t.Run(tt.name, func(t *testing.T) { 232 | if got := FilterFloat32(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 233 | t.Errorf("FilterFloat32() = %v, want %v", got, tt.want) 234 | } 235 | }) 236 | } 237 | } 238 | 239 | func TestFilterFloat64(t *testing.T) { 240 | type args struct { 241 | a []float64 242 | keep func(x float64) bool 243 | } 244 | tests := []struct { 245 | name string 246 | args args 247 | want []float64 248 | }{ 249 | { 250 | name: "nil slice", 251 | args: args{ 252 | a: nil, 253 | keep: func(float64) bool { panic("not implemented") }, 254 | }, 255 | want: nil, 256 | }, 257 | { 258 | name: "empty slice", 259 | args: args{ 260 | a: []float64{}, 261 | keep: func(float64) bool { panic("not implemented") }, 262 | }, 263 | want: []float64{}, 264 | }, 265 | { 266 | name: "non empty slice", 267 | args: args{ 268 | a: []float64{1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9}, 269 | keep: func(x float64) bool { 270 | return x < 5.5 271 | }, 272 | }, 273 | want: []float64{1.1, 2.2, 3.3, 4.4}, 274 | }, 275 | } 276 | for _, tt := range tests { 277 | t.Run(tt.name, func(t *testing.T) { 278 | if got := FilterFloat64(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 279 | t.Errorf("FilterFloat64() = %v, want %v", got, tt.want) 280 | } 281 | }) 282 | } 283 | } 284 | 285 | func TestFilterInt(t *testing.T) { 286 | type args struct { 287 | a []int 288 | keep func(x int) bool 289 | } 290 | tests := []struct { 291 | name string 292 | args args 293 | want []int 294 | }{ 295 | { 296 | name: "nil slice", 297 | args: args{ 298 | a: nil, 299 | keep: func(int) bool { panic("not implemented") }, 300 | }, 301 | want: nil, 302 | }, 303 | { 304 | name: "empty slice", 305 | args: args{ 306 | a: []int{}, 307 | keep: func(int) bool { panic("not implemented") }, 308 | }, 309 | want: []int{}, 310 | }, 311 | { 312 | name: "non empty slice", 313 | args: args{ 314 | a: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 315 | keep: func(x int) bool { 316 | return x < 5 317 | }, 318 | }, 319 | want: []int{1, 2, 3, 4}, 320 | }, 321 | } 322 | for _, tt := range tests { 323 | t.Run(tt.name, func(t *testing.T) { 324 | if got := FilterInt(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 325 | t.Errorf("FilterInt() = %v, want %v", got, tt.want) 326 | } 327 | }) 328 | } 329 | } 330 | 331 | func TestFilterInt16(t *testing.T) { 332 | type args struct { 333 | a []int16 334 | keep func(x int16) bool 335 | } 336 | tests := []struct { 337 | name string 338 | args args 339 | want []int16 340 | }{ 341 | { 342 | name: "nil slice", 343 | args: args{ 344 | a: nil, 345 | keep: func(int16) bool { panic("not implemented") }, 346 | }, 347 | want: nil, 348 | }, 349 | { 350 | name: "empty slice", 351 | args: args{ 352 | a: []int16{}, 353 | keep: func(int16) bool { panic("not implemented") }, 354 | }, 355 | want: []int16{}, 356 | }, 357 | { 358 | name: "non empty slice", 359 | args: args{ 360 | a: []int16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 361 | keep: func(x int16) bool { 362 | return x < 5 363 | }, 364 | }, 365 | want: []int16{1, 2, 3, 4}, 366 | }, 367 | } 368 | for _, tt := range tests { 369 | t.Run(tt.name, func(t *testing.T) { 370 | if got := FilterInt16(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 371 | t.Errorf("FilterInt16() = %v, want %v", got, tt.want) 372 | } 373 | }) 374 | } 375 | } 376 | 377 | func TestFilterInt32(t *testing.T) { 378 | type args struct { 379 | a []int32 380 | keep func(x int32) bool 381 | } 382 | tests := []struct { 383 | name string 384 | args args 385 | want []int32 386 | }{ 387 | { 388 | name: "nil slice", 389 | args: args{ 390 | a: nil, 391 | keep: func(int32) bool { panic("not implemented") }, 392 | }, 393 | want: nil, 394 | }, 395 | { 396 | name: "empty slice", 397 | args: args{ 398 | a: []int32{}, 399 | keep: func(int32) bool { panic("not implemented") }, 400 | }, 401 | want: []int32{}, 402 | }, 403 | { 404 | name: "non empty slice", 405 | args: args{ 406 | a: []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 407 | keep: func(x int32) bool { 408 | return x < 5 409 | }, 410 | }, 411 | want: []int32{1, 2, 3, 4}, 412 | }, 413 | } 414 | for _, tt := range tests { 415 | t.Run(tt.name, func(t *testing.T) { 416 | if got := FilterInt32(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 417 | t.Errorf("FilterInt32() = %v, want %v", got, tt.want) 418 | } 419 | }) 420 | } 421 | } 422 | 423 | func TestFilterInt64(t *testing.T) { 424 | type args struct { 425 | a []int64 426 | keep func(x int64) bool 427 | } 428 | tests := []struct { 429 | name string 430 | args args 431 | want []int64 432 | }{ 433 | { 434 | name: "nil slice", 435 | args: args{ 436 | a: nil, 437 | keep: func(int64) bool { panic("not implemented") }, 438 | }, 439 | want: nil, 440 | }, 441 | { 442 | name: "empty slice", 443 | args: args{ 444 | a: []int64{}, 445 | keep: func(int64) bool { panic("not implemented") }, 446 | }, 447 | want: []int64{}, 448 | }, 449 | { 450 | name: "non empty slice", 451 | args: args{ 452 | a: []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 453 | keep: func(x int64) bool { 454 | return x < 5 455 | }, 456 | }, 457 | want: []int64{1, 2, 3, 4}, 458 | }, 459 | } 460 | for _, tt := range tests { 461 | t.Run(tt.name, func(t *testing.T) { 462 | if got := FilterInt64(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 463 | t.Errorf("FilterInt64() = %v, want %v", got, tt.want) 464 | } 465 | }) 466 | } 467 | } 468 | 469 | func TestFilterInt8(t *testing.T) { 470 | type args struct { 471 | a []int8 472 | keep func(x int8) bool 473 | } 474 | tests := []struct { 475 | name string 476 | args args 477 | want []int8 478 | }{ 479 | { 480 | name: "nil slice", 481 | args: args{ 482 | a: nil, 483 | keep: func(int8) bool { panic("not implemented") }, 484 | }, 485 | want: nil, 486 | }, 487 | { 488 | name: "empty slice", 489 | args: args{ 490 | a: []int8{}, 491 | keep: func(int8) bool { panic("not implemented") }, 492 | }, 493 | want: []int8{}, 494 | }, 495 | { 496 | name: "non empty slice", 497 | args: args{ 498 | a: []int8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 499 | keep: func(x int8) bool { 500 | return x < 5 501 | }, 502 | }, 503 | want: []int8{1, 2, 3, 4}, 504 | }, 505 | } 506 | for _, tt := range tests { 507 | t.Run(tt.name, func(t *testing.T) { 508 | if got := FilterInt8(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 509 | t.Errorf("FilterInt8() = %v, want %v", got, tt.want) 510 | } 511 | }) 512 | } 513 | } 514 | 515 | func TestFilterRune(t *testing.T) { 516 | type args struct { 517 | a []rune 518 | keep func(x rune) bool 519 | } 520 | tests := []struct { 521 | name string 522 | args args 523 | want []rune 524 | }{ 525 | { 526 | name: "nil slice", 527 | args: args{ 528 | a: nil, 529 | keep: func(rune) bool { panic("not implemented") }, 530 | }, 531 | want: nil, 532 | }, 533 | { 534 | name: "empty slice", 535 | args: args{ 536 | a: []rune{}, 537 | keep: func(rune) bool { panic("not implemented") }, 538 | }, 539 | want: []rune{}, 540 | }, 541 | { 542 | name: "non empty slice", 543 | args: args{ 544 | a: []rune{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 545 | keep: func(x rune) bool { 546 | return x < 5 547 | }, 548 | }, 549 | want: []rune{1, 2, 3, 4}, 550 | }, 551 | } 552 | for _, tt := range tests { 553 | t.Run(tt.name, func(t *testing.T) { 554 | if got := FilterRune(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 555 | t.Errorf("FilterRune() = %v, want %v", got, tt.want) 556 | } 557 | }) 558 | } 559 | } 560 | 561 | func TestFilterString(t *testing.T) { 562 | type args struct { 563 | a []string 564 | keep func(x string) bool 565 | } 566 | tests := []struct { 567 | name string 568 | args args 569 | want []string 570 | }{ 571 | { 572 | name: "nil slice", 573 | args: args{ 574 | a: nil, 575 | keep: func(string) bool { panic("not implemented") }, 576 | }, 577 | want: nil, 578 | }, 579 | { 580 | name: "empty slice", 581 | args: args{ 582 | a: []string{}, 583 | keep: func(string) bool { panic("not implemented") }, 584 | }, 585 | want: []string{}, 586 | }, 587 | { 588 | name: "non empty slice", 589 | args: args{ 590 | a: []string{"a", "b", "c", "d"}, 591 | keep: func(x string) bool { 592 | return x == "a" || x == "d" 593 | }, 594 | }, 595 | want: []string{"a", "d"}, 596 | }, 597 | } 598 | for _, tt := range tests { 599 | t.Run(tt.name, func(t *testing.T) { 600 | if got := FilterString(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 601 | t.Errorf("FilterString() = %v, want %v", got, tt.want) 602 | } 603 | }) 604 | } 605 | } 606 | 607 | func TestFilterUint(t *testing.T) { 608 | type args struct { 609 | a []uint 610 | keep func(x uint) bool 611 | } 612 | tests := []struct { 613 | name string 614 | args args 615 | want []uint 616 | }{ 617 | { 618 | name: "nil slice", 619 | args: args{ 620 | a: nil, 621 | keep: func(uint) bool { panic("not implemented") }, 622 | }, 623 | want: nil, 624 | }, 625 | { 626 | name: "empty slice", 627 | args: args{ 628 | a: []uint{}, 629 | keep: func(uint) bool { panic("not implemented") }, 630 | }, 631 | want: []uint{}, 632 | }, 633 | { 634 | name: "non empty slice", 635 | args: args{ 636 | a: []uint{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 637 | keep: func(x uint) bool { 638 | return x < 5 639 | }, 640 | }, 641 | want: []uint{1, 2, 3, 4}, 642 | }, 643 | } 644 | for _, tt := range tests { 645 | t.Run(tt.name, func(t *testing.T) { 646 | if got := FilterUint(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 647 | t.Errorf("FilterUint() = %v, want %v", got, tt.want) 648 | } 649 | }) 650 | } 651 | } 652 | 653 | func TestFilterUint16(t *testing.T) { 654 | type args struct { 655 | a []uint16 656 | keep func(x uint16) bool 657 | } 658 | tests := []struct { 659 | name string 660 | args args 661 | want []uint16 662 | }{ 663 | { 664 | name: "nil slice", 665 | args: args{ 666 | a: nil, 667 | keep: func(uint16) bool { panic("not implemented") }, 668 | }, 669 | want: nil, 670 | }, 671 | { 672 | name: "empty slice", 673 | args: args{ 674 | a: []uint16{}, 675 | keep: func(uint16) bool { panic("not implemented") }, 676 | }, 677 | want: []uint16{}, 678 | }, 679 | { 680 | name: "non empty slice", 681 | args: args{ 682 | a: []uint16{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 683 | keep: func(x uint16) bool { 684 | return x < 5 685 | }, 686 | }, 687 | want: []uint16{1, 2, 3, 4}, 688 | }, 689 | } 690 | for _, tt := range tests { 691 | t.Run(tt.name, func(t *testing.T) { 692 | if got := FilterUint16(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 693 | t.Errorf("FilterUint16() = %v, want %v", got, tt.want) 694 | } 695 | }) 696 | } 697 | } 698 | 699 | func TestFilterUint32(t *testing.T) { 700 | type args struct { 701 | a []uint32 702 | keep func(x uint32) bool 703 | } 704 | tests := []struct { 705 | name string 706 | args args 707 | want []uint32 708 | }{ 709 | { 710 | name: "nil slice", 711 | args: args{ 712 | a: nil, 713 | keep: func(uint32) bool { panic("not implemented") }, 714 | }, 715 | want: nil, 716 | }, 717 | { 718 | name: "empty slice", 719 | args: args{ 720 | a: []uint32{}, 721 | keep: func(uint32) bool { panic("not implemented") }, 722 | }, 723 | want: []uint32{}, 724 | }, 725 | { 726 | name: "non empty slice", 727 | args: args{ 728 | a: []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 729 | keep: func(x uint32) bool { 730 | return x < 5 731 | }, 732 | }, 733 | want: []uint32{1, 2, 3, 4}, 734 | }, 735 | } 736 | for _, tt := range tests { 737 | t.Run(tt.name, func(t *testing.T) { 738 | if got := FilterUint32(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 739 | t.Errorf("FilterUint32() = %v, want %v", got, tt.want) 740 | } 741 | }) 742 | } 743 | } 744 | 745 | func TestFilterUint64(t *testing.T) { 746 | type args struct { 747 | a []uint64 748 | keep func(x uint64) bool 749 | } 750 | tests := []struct { 751 | name string 752 | args args 753 | want []uint64 754 | }{ 755 | { 756 | name: "nil slice", 757 | args: args{ 758 | a: nil, 759 | keep: func(uint64) bool { panic("not implemented") }, 760 | }, 761 | want: nil, 762 | }, 763 | { 764 | name: "empty slice", 765 | args: args{ 766 | a: []uint64{}, 767 | keep: func(uint64) bool { panic("not implemented") }, 768 | }, 769 | want: []uint64{}, 770 | }, 771 | { 772 | name: "non empty slice", 773 | args: args{ 774 | a: []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 775 | keep: func(x uint64) bool { 776 | return x < 5 777 | }, 778 | }, 779 | want: []uint64{1, 2, 3, 4}, 780 | }, 781 | } 782 | for _, tt := range tests { 783 | t.Run(tt.name, func(t *testing.T) { 784 | if got := FilterUint64(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 785 | t.Errorf("FilterUint64() = %v, want %v", got, tt.want) 786 | } 787 | }) 788 | } 789 | } 790 | 791 | func TestFilterUint8(t *testing.T) { 792 | type args struct { 793 | a []uint8 794 | keep func(x uint8) bool 795 | } 796 | tests := []struct { 797 | name string 798 | args args 799 | want []uint8 800 | }{ 801 | { 802 | name: "nil slice", 803 | args: args{ 804 | a: nil, 805 | keep: func(uint8) bool { panic("not implemented") }, 806 | }, 807 | want: nil, 808 | }, 809 | { 810 | name: "empty slice", 811 | args: args{ 812 | a: []uint8{}, 813 | keep: func(uint8) bool { panic("not implemented") }, 814 | }, 815 | want: []uint8{}, 816 | }, 817 | { 818 | name: "non empty slice", 819 | args: args{ 820 | a: []uint8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 821 | keep: func(x uint8) bool { 822 | return x < 5 823 | }, 824 | }, 825 | want: []uint8{1, 2, 3, 4}, 826 | }, 827 | } 828 | for _, tt := range tests { 829 | t.Run(tt.name, func(t *testing.T) { 830 | if got := FilterUint8(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 831 | t.Errorf("FilterUint8() = %v, want %v", got, tt.want) 832 | } 833 | }) 834 | } 835 | } 836 | 837 | func TestFilterUintptr(t *testing.T) { 838 | type args struct { 839 | a []uintptr 840 | keep func(x uintptr) bool 841 | } 842 | tests := []struct { 843 | name string 844 | args args 845 | want []uintptr 846 | }{ 847 | { 848 | name: "nil slice", 849 | args: args{ 850 | a: nil, 851 | keep: func(uintptr) bool { panic("not implemented") }, 852 | }, 853 | want: nil, 854 | }, 855 | { 856 | name: "empty slice", 857 | args: args{ 858 | a: []uintptr{}, 859 | keep: func(uintptr) bool { panic("not implemented") }, 860 | }, 861 | want: []uintptr{}, 862 | }, 863 | { 864 | name: "non empty slice", 865 | args: args{ 866 | a: []uintptr{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 867 | keep: func(x uintptr) bool { 868 | return x < 5 869 | }, 870 | }, 871 | want: []uintptr{1, 2, 3, 4}, 872 | }, 873 | } 874 | for _, tt := range tests { 875 | t.Run(tt.name, func(t *testing.T) { 876 | if got := FilterUintptr(tt.args.a, tt.args.keep); !reflect.DeepEqual(got, tt.want) { 877 | t.Errorf("FilterUintptr() = %v, want %v", got, tt.want) 878 | } 879 | }) 880 | } 881 | } 882 | 883 | func ExampleFilterInt() { 884 | a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 885 | keep := func(x int) bool { 886 | return x%2 == 0 887 | } 888 | a = FilterInt(a, keep) 889 | fmt.Println(a) 890 | // Output [2, 4, 6, 8 , 10] 891 | } 892 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/psampaz/slice 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/psampaz/slice/c5bd6e8e53c7c45a17e0228293377ca915fcf15f/go.sum -------------------------------------------------------------------------------- /max.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import "errors" 4 | 5 | // MaxByte returns the maximum value of a byte slice or an error in case of a nil or empty slice 6 | func MaxByte(a []byte) (byte, error) { 7 | if len(a) == 0 { 8 | return 0, errors.New("returns the maximum of a nil or empty slice") 9 | } 10 | 11 | max := a[0] 12 | for k := 1; k < len(a); k++ { 13 | if a[k] > max { 14 | max = a[k] 15 | } 16 | } 17 | 18 | return max, nil 19 | } 20 | 21 | // MaxFloat32 returns the maximum value of a float32 slice or an error in case of a nil or empty slice 22 | func MaxFloat32(a []float32) (float32, error) { 23 | if len(a) == 0 { 24 | return 0, errors.New("returns the maximum of a nil or empty slice") 25 | } 26 | 27 | max := a[0] 28 | for k := 1; k < len(a); k++ { 29 | if a[k] > max { 30 | max = a[k] 31 | } 32 | } 33 | 34 | return max, nil 35 | } 36 | 37 | // MaxFloat64 returns the maximum value of a float64 slice or an error in case of a nil or empty slice 38 | func MaxFloat64(a []float64) (float64, error) { 39 | if len(a) == 0 { 40 | return 0, errors.New("returns the maximum of a nil or empty slice") 41 | } 42 | 43 | max := a[0] 44 | for k := 1; k < len(a); k++ { 45 | if a[k] > max { 46 | max = a[k] 47 | } 48 | } 49 | 50 | return max, nil 51 | } 52 | 53 | // MaxInt returns the maximum value of a int slice or an error in case of a nil or empty slice 54 | func MaxInt(a []int) (int, error) { 55 | if len(a) == 0 { 56 | return 0, errors.New("returns the maximum of a nil or empty slice") 57 | } 58 | 59 | max := a[0] 60 | for k := 1; k < len(a); k++ { 61 | if a[k] > max { 62 | max = a[k] 63 | } 64 | } 65 | 66 | return max, nil 67 | } 68 | 69 | // MaxInt8 returns the maximum value of a int8 slice or an error in case of a nil or empty slice 70 | func MaxInt8(a []int8) (int8, error) { 71 | if len(a) == 0 { 72 | return 0, errors.New("returns the maximum of a nil or empty slice") 73 | } 74 | 75 | max := a[0] 76 | for k := 1; k < len(a); k++ { 77 | if a[k] > max { 78 | max = a[k] 79 | } 80 | } 81 | 82 | return max, nil 83 | } 84 | 85 | // MaxInt16 returns the maximum value of a int16 slice or an error in case of a nil or empty slice 86 | func MaxInt16(a []int16) (int16, error) { 87 | if len(a) == 0 { 88 | return 0, errors.New("returns the maximum of a nil or empty slice") 89 | } 90 | 91 | max := a[0] 92 | for k := 1; k < len(a); k++ { 93 | if a[k] > max { 94 | max = a[k] 95 | } 96 | } 97 | 98 | return max, nil 99 | } 100 | 101 | // MaxInt32 returns the maximum value of a int32 slice or an error in case of a nil or empty slice 102 | func MaxInt32(a []int32) (int32, error) { 103 | if len(a) == 0 { 104 | return 0, errors.New("returns the maximum of a nil or empty slice") 105 | } 106 | 107 | max := a[0] 108 | for k := 1; k < len(a); k++ { 109 | if a[k] > max { 110 | max = a[k] 111 | } 112 | } 113 | 114 | return max, nil 115 | } 116 | 117 | // MaxInt64 returns the maximum value of a int64 slice or an error in case of a nil or empty slice 118 | func MaxInt64(a []int64) (int64, error) { 119 | if len(a) == 0 { 120 | return 0, errors.New("returns the maximum of a nil or empty slice") 121 | } 122 | 123 | max := a[0] 124 | for k := 1; k < len(a); k++ { 125 | if a[k] > max { 126 | max = a[k] 127 | } 128 | } 129 | 130 | return max, nil 131 | } 132 | 133 | // MaxRune returns the maximum value of a rune slice or an error in case of a nil or empty slice 134 | func MaxRune(a []rune) (rune, error) { 135 | if len(a) == 0 { 136 | return 0, errors.New("returns the maximum of a nil or empty slice") 137 | } 138 | 139 | max := a[0] 140 | for k := 1; k < len(a); k++ { 141 | if a[k] > max { 142 | max = a[k] 143 | } 144 | } 145 | 146 | return max, nil 147 | } 148 | 149 | // MaxUint returns the maximum value of a uint slice or an error in case of a nil or empty slice 150 | func MaxUint(a []uint) (uint, error) { 151 | if len(a) == 0 { 152 | return 0, errors.New("returns the maximum of a nil or empty slice") 153 | } 154 | 155 | max := a[0] 156 | for k := 1; k < len(a); k++ { 157 | if a[k] > max { 158 | max = a[k] 159 | } 160 | } 161 | 162 | return max, nil 163 | } 164 | 165 | // MaxUint8 returns the maximum value of a uint8 slice or an error in case of a nil or empty slice 166 | func MaxUint8(a []uint8) (uint8, error) { 167 | if len(a) == 0 { 168 | return 0, errors.New("returns the maximum of a nil or empty slice") 169 | } 170 | 171 | max := a[0] 172 | for k := 1; k < len(a); k++ { 173 | if a[k] > max { 174 | max = a[k] 175 | } 176 | } 177 | 178 | return max, nil 179 | } 180 | 181 | // MaxUint16 returns the maximum value of a uint16 slice or an error in case of a nil or empty slice 182 | func MaxUint16(a []uint16) (uint16, error) { 183 | if len(a) == 0 { 184 | return 0, errors.New("returns the maximum of a nil or empty slice") 185 | } 186 | 187 | max := a[0] 188 | for k := 1; k < len(a); k++ { 189 | if a[k] > max { 190 | max = a[k] 191 | } 192 | } 193 | 194 | return max, nil 195 | } 196 | 197 | // MaxUint32 returns the maximum value of a uint32 slice or an error in case of a nil or empty slice 198 | func MaxUint32(a []uint32) (uint32, error) { 199 | if len(a) == 0 { 200 | return 0, errors.New("returns the maximum of a nil or empty slice") 201 | } 202 | 203 | max := a[0] 204 | for k := 1; k < len(a); k++ { 205 | if a[k] > max { 206 | max = a[k] 207 | } 208 | } 209 | 210 | return max, nil 211 | } 212 | 213 | // MaxUint64 returns the maximum value of a uint64 slice or an error in case of a nil or empty slice 214 | func MaxUint64(a []uint64) (uint64, error) { 215 | if len(a) == 0 { 216 | return 0, errors.New("returns the maximum of a nil or empty slice") 217 | } 218 | 219 | max := a[0] 220 | for k := 1; k < len(a); k++ { 221 | if a[k] > max { 222 | max = a[k] 223 | } 224 | } 225 | 226 | return max, nil 227 | } 228 | 229 | // MaxUintptr returns the maximum value of a uintptr slice or an error in case of a nil or empty slice 230 | func MaxUintptr(a []uintptr) (uintptr, error) { 231 | if len(a) == 0 { 232 | return 0, errors.New("returns the maximum of a nil or empty slice") 233 | } 234 | 235 | max := a[0] 236 | for k := 1; k < len(a); k++ { 237 | if a[k] > max { 238 | max = a[k] 239 | } 240 | } 241 | 242 | return max, nil 243 | } 244 | -------------------------------------------------------------------------------- /max_test.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestMaxByte(t *testing.T) { 9 | type args struct { 10 | a []byte 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want byte 16 | wantErr bool 17 | }{ 18 | { 19 | name: "nil slice", 20 | args: args{ 21 | a: nil, 22 | }, 23 | want: 0, 24 | wantErr: true, 25 | }, 26 | { 27 | name: "empty slice", 28 | args: args{ 29 | a: []byte{}, 30 | }, 31 | want: 0, 32 | wantErr: true, 33 | }, 34 | { 35 | name: "non empty slice", 36 | args: args{ 37 | a: []byte{1, 4, 5, 34, 2, 100}, 38 | }, 39 | want: 100, 40 | wantErr: false, 41 | }, 42 | } 43 | for _, tt := range tests { 44 | t.Run(tt.name, func(t *testing.T) { 45 | got, err := MaxByte(tt.args.a) 46 | if (err != nil) != tt.wantErr { 47 | t.Errorf("MaxByte() error = %v, wantErr %v", err, tt.wantErr) 48 | return 49 | } 50 | if got != tt.want { 51 | t.Errorf("MaxByte() = %v, want %v", got, tt.want) 52 | } 53 | }) 54 | } 55 | } 56 | 57 | func TestMaxFloat32(t *testing.T) { 58 | type args struct { 59 | a []float32 60 | } 61 | tests := []struct { 62 | name string 63 | args args 64 | want float32 65 | wantErr bool 66 | }{ 67 | { 68 | name: "nil slice", 69 | args: args{ 70 | a: nil, 71 | }, 72 | want: 0, 73 | wantErr: true, 74 | }, 75 | { 76 | name: "empty slice", 77 | args: args{ 78 | a: []float32{}, 79 | }, 80 | want: 0, 81 | wantErr: true, 82 | }, 83 | { 84 | name: "non empty slice", 85 | args: args{ 86 | a: []float32{1.1, 4.1, 5.1, -34.4, 2.2, 100.1}, 87 | }, 88 | want: 100.1, 89 | wantErr: false, 90 | }, 91 | } 92 | for _, tt := range tests { 93 | t.Run(tt.name, func(t *testing.T) { 94 | got, err := MaxFloat32(tt.args.a) 95 | if (err != nil) != tt.wantErr { 96 | t.Errorf("MaxFloat32() error = %v, wantErr %v", err, tt.wantErr) 97 | return 98 | } 99 | if got != tt.want { 100 | t.Errorf("MaxFloat32() = %v, want %v", got, tt.want) 101 | } 102 | }) 103 | } 104 | } 105 | 106 | func TestMaxFloat64(t *testing.T) { 107 | type args struct { 108 | a []float64 109 | } 110 | tests := []struct { 111 | name string 112 | args args 113 | want float64 114 | wantErr bool 115 | }{ 116 | { 117 | name: "nil slice", 118 | args: args{ 119 | a: nil, 120 | }, 121 | want: 0, 122 | wantErr: true, 123 | }, 124 | { 125 | name: "empty slice", 126 | args: args{ 127 | a: []float64{}, 128 | }, 129 | want: 0, 130 | wantErr: true, 131 | }, 132 | { 133 | name: "non empty slice", 134 | args: args{ 135 | a: []float64{1.1, 4.1, 5.1, -34.4, 2.2, 100.1}, 136 | }, 137 | want: 100.1, 138 | wantErr: false, 139 | }, 140 | } 141 | for _, tt := range tests { 142 | t.Run(tt.name, func(t *testing.T) { 143 | got, err := MaxFloat64(tt.args.a) 144 | if (err != nil) != tt.wantErr { 145 | t.Errorf("MaxFloat64() error = %v, wantErr %v", err, tt.wantErr) 146 | return 147 | } 148 | if got != tt.want { 149 | t.Errorf("MaxFloat64() = %v, want %v", got, tt.want) 150 | } 151 | }) 152 | } 153 | } 154 | 155 | func TestMaxInt(t *testing.T) { 156 | type args struct { 157 | a []int 158 | } 159 | tests := []struct { 160 | name string 161 | args args 162 | want int 163 | wantErr bool 164 | }{ 165 | { 166 | name: "nil slice", 167 | args: args{ 168 | a: nil, 169 | }, 170 | want: 0, 171 | wantErr: true, 172 | }, 173 | { 174 | name: "empty slice", 175 | args: args{ 176 | a: []int{}, 177 | }, 178 | want: 0, 179 | wantErr: true, 180 | }, 181 | { 182 | name: "non empty slice", 183 | args: args{ 184 | a: []int{1, 4, 5, -34, 2, 100}, 185 | }, 186 | want: 100, 187 | wantErr: false, 188 | }, 189 | } 190 | for _, tt := range tests { 191 | t.Run(tt.name, func(t *testing.T) { 192 | got, err := MaxInt(tt.args.a) 193 | if (err != nil) != tt.wantErr { 194 | t.Errorf("MaxInt() error = %v, wantErr %v", err, tt.wantErr) 195 | return 196 | } 197 | if got != tt.want { 198 | t.Errorf("MaxInt() = %v, want %v", got, tt.want) 199 | } 200 | }) 201 | } 202 | } 203 | 204 | func TestMaxInt8(t *testing.T) { 205 | type args struct { 206 | a []int8 207 | } 208 | tests := []struct { 209 | name string 210 | args args 211 | want int8 212 | wantErr bool 213 | }{ 214 | { 215 | name: "nil slice", 216 | args: args{ 217 | a: nil, 218 | }, 219 | want: 0, 220 | wantErr: true, 221 | }, 222 | { 223 | name: "empty slice", 224 | args: args{ 225 | a: []int8{}, 226 | }, 227 | want: 0, 228 | wantErr: true, 229 | }, 230 | { 231 | name: "non empty slice", 232 | args: args{ 233 | a: []int8{1, 4, 5, -34, 2, 100}, 234 | }, 235 | want: 100, 236 | wantErr: false, 237 | }, 238 | } 239 | for _, tt := range tests { 240 | t.Run(tt.name, func(t *testing.T) { 241 | got, err := MaxInt8(tt.args.a) 242 | if (err != nil) != tt.wantErr { 243 | t.Errorf("MaxInt8() error = %v, wantErr %v", err, tt.wantErr) 244 | return 245 | } 246 | if got != tt.want { 247 | t.Errorf("MaxInt8() = %v, want %v", got, tt.want) 248 | } 249 | }) 250 | } 251 | } 252 | 253 | func TestMaxInt16(t *testing.T) { 254 | type args struct { 255 | a []int16 256 | } 257 | tests := []struct { 258 | name string 259 | args args 260 | want int16 261 | wantErr bool 262 | }{ 263 | { 264 | name: "nil slice", 265 | args: args{ 266 | a: nil, 267 | }, 268 | want: 0, 269 | wantErr: true, 270 | }, 271 | { 272 | name: "empty slice", 273 | args: args{ 274 | a: []int16{}, 275 | }, 276 | want: 0, 277 | wantErr: true, 278 | }, 279 | { 280 | name: "non empty slice", 281 | args: args{ 282 | a: []int16{1, 4, 5, -34, 2, 100}, 283 | }, 284 | want: 100, 285 | wantErr: false, 286 | }, 287 | } 288 | for _, tt := range tests { 289 | t.Run(tt.name, func(t *testing.T) { 290 | got, err := MaxInt16(tt.args.a) 291 | if (err != nil) != tt.wantErr { 292 | t.Errorf("MaxInt16() error = %v, wantErr %v", err, tt.wantErr) 293 | return 294 | } 295 | if got != tt.want { 296 | t.Errorf("MaxInt16() = %v, want %v", got, tt.want) 297 | } 298 | }) 299 | } 300 | } 301 | 302 | func TestMaxInt32(t *testing.T) { 303 | type args struct { 304 | a []int32 305 | } 306 | tests := []struct { 307 | name string 308 | args args 309 | want int32 310 | wantErr bool 311 | }{ 312 | { 313 | name: "nil slice", 314 | args: args{ 315 | a: nil, 316 | }, 317 | want: 0, 318 | wantErr: true, 319 | }, 320 | { 321 | name: "empty slice", 322 | args: args{ 323 | a: []int32{}, 324 | }, 325 | want: 0, 326 | wantErr: true, 327 | }, 328 | { 329 | name: "non empty slice", 330 | args: args{ 331 | a: []int32{1, 4, 5, -34, 2, 100}, 332 | }, 333 | want: 100, 334 | wantErr: false, 335 | }, 336 | } 337 | for _, tt := range tests { 338 | t.Run(tt.name, func(t *testing.T) { 339 | got, err := MaxInt32(tt.args.a) 340 | if (err != nil) != tt.wantErr { 341 | t.Errorf("MaxInt32() error = %v, wantErr %v", err, tt.wantErr) 342 | return 343 | } 344 | if got != tt.want { 345 | t.Errorf("MaxInt32() = %v, want %v", got, tt.want) 346 | } 347 | }) 348 | } 349 | } 350 | 351 | func TestMaxInt64(t *testing.T) { 352 | type args struct { 353 | a []int64 354 | } 355 | tests := []struct { 356 | name string 357 | args args 358 | want int64 359 | wantErr bool 360 | }{ 361 | { 362 | name: "nil slice", 363 | args: args{ 364 | a: nil, 365 | }, 366 | want: 0, 367 | wantErr: true, 368 | }, 369 | { 370 | name: "empty slice", 371 | args: args{ 372 | a: []int64{}, 373 | }, 374 | want: 0, 375 | wantErr: true, 376 | }, 377 | { 378 | name: "non empty slice", 379 | args: args{ 380 | a: []int64{1, 4, 5, -34, 2, 100}, 381 | }, 382 | want: 100, 383 | wantErr: false, 384 | }, 385 | } 386 | for _, tt := range tests { 387 | t.Run(tt.name, func(t *testing.T) { 388 | got, err := MaxInt64(tt.args.a) 389 | if (err != nil) != tt.wantErr { 390 | t.Errorf("MaxInt64() error = %v, wantErr %v", err, tt.wantErr) 391 | return 392 | } 393 | if got != tt.want { 394 | t.Errorf("MaxInt64() = %v, want %v", got, tt.want) 395 | } 396 | }) 397 | } 398 | } 399 | 400 | func TestMaxRune(t *testing.T) { 401 | type args struct { 402 | a []rune 403 | } 404 | tests := []struct { 405 | name string 406 | args args 407 | want rune 408 | wantErr bool 409 | }{ 410 | { 411 | name: "nil slice", 412 | args: args{ 413 | a: nil, 414 | }, 415 | want: 0, 416 | wantErr: true, 417 | }, 418 | { 419 | name: "empty slice", 420 | args: args{ 421 | a: []rune{}, 422 | }, 423 | want: 0, 424 | wantErr: true, 425 | }, 426 | { 427 | name: "non empty slice", 428 | args: args{ 429 | a: []rune{1, 4, 5, -34, 2, 100}, 430 | }, 431 | want: 100, 432 | wantErr: false, 433 | }, 434 | } 435 | for _, tt := range tests { 436 | t.Run(tt.name, func(t *testing.T) { 437 | got, err := MaxRune(tt.args.a) 438 | if (err != nil) != tt.wantErr { 439 | t.Errorf("MaxRune() error = %v, wantErr %v", err, tt.wantErr) 440 | return 441 | } 442 | if got != tt.want { 443 | t.Errorf("MaxRune() = %v, want %v", got, tt.want) 444 | } 445 | }) 446 | } 447 | } 448 | 449 | func TestMaxUint(t *testing.T) { 450 | type args struct { 451 | a []uint 452 | } 453 | tests := []struct { 454 | name string 455 | args args 456 | want uint 457 | wantErr bool 458 | }{ 459 | { 460 | name: "nil slice", 461 | args: args{ 462 | a: nil, 463 | }, 464 | want: 0, 465 | wantErr: true, 466 | }, 467 | { 468 | name: "empty slice", 469 | args: args{ 470 | a: []uint{}, 471 | }, 472 | want: 0, 473 | wantErr: true, 474 | }, 475 | { 476 | name: "non empty slice", 477 | args: args{ 478 | a: []uint{1, 4, 5, 34, 2, 100}, 479 | }, 480 | want: 100, 481 | wantErr: false, 482 | }, 483 | } 484 | for _, tt := range tests { 485 | t.Run(tt.name, func(t *testing.T) { 486 | got, err := MaxUint(tt.args.a) 487 | if (err != nil) != tt.wantErr { 488 | t.Errorf("MaxUint() error = %v, wantErr %v", err, tt.wantErr) 489 | return 490 | } 491 | if got != tt.want { 492 | t.Errorf("MaxUint() = %v, want %v", got, tt.want) 493 | } 494 | }) 495 | } 496 | } 497 | 498 | func TestMaxUint16(t *testing.T) { 499 | type args struct { 500 | a []uint16 501 | } 502 | tests := []struct { 503 | name string 504 | args args 505 | want uint16 506 | wantErr bool 507 | }{ 508 | { 509 | name: "nil slice", 510 | args: args{ 511 | a: nil, 512 | }, 513 | want: 0, 514 | wantErr: true, 515 | }, 516 | { 517 | name: "empty slice", 518 | args: args{ 519 | a: []uint16{}, 520 | }, 521 | want: 0, 522 | wantErr: true, 523 | }, 524 | { 525 | name: "non empty slice", 526 | args: args{ 527 | a: []uint16{1, 4, 5, 34, 2, 100}, 528 | }, 529 | want: 100, 530 | wantErr: false, 531 | }, 532 | } 533 | for _, tt := range tests { 534 | t.Run(tt.name, func(t *testing.T) { 535 | got, err := MaxUint16(tt.args.a) 536 | if (err != nil) != tt.wantErr { 537 | t.Errorf("MaxUint16() error = %v, wantErr %v", err, tt.wantErr) 538 | return 539 | } 540 | if got != tt.want { 541 | t.Errorf("MaxUint16() = %v, want %v", got, tt.want) 542 | } 543 | }) 544 | } 545 | } 546 | 547 | func TestMaxUint32(t *testing.T) { 548 | type args struct { 549 | a []uint32 550 | } 551 | tests := []struct { 552 | name string 553 | args args 554 | want uint32 555 | wantErr bool 556 | }{ 557 | { 558 | name: "nil slice", 559 | args: args{ 560 | a: nil, 561 | }, 562 | want: 0, 563 | wantErr: true, 564 | }, 565 | { 566 | name: "empty slice", 567 | args: args{ 568 | a: []uint32{}, 569 | }, 570 | want: 0, 571 | wantErr: true, 572 | }, 573 | { 574 | name: "non empty slice", 575 | args: args{ 576 | a: []uint32{1, 4, 5, 34, 2, 100}, 577 | }, 578 | want: 100, 579 | wantErr: false, 580 | }, 581 | } 582 | for _, tt := range tests { 583 | t.Run(tt.name, func(t *testing.T) { 584 | got, err := MaxUint32(tt.args.a) 585 | if (err != nil) != tt.wantErr { 586 | t.Errorf("MaxUint32() error = %v, wantErr %v", err, tt.wantErr) 587 | return 588 | } 589 | if got != tt.want { 590 | t.Errorf("MaxUint32() = %v, want %v", got, tt.want) 591 | } 592 | }) 593 | } 594 | } 595 | 596 | func TestMaxUint64(t *testing.T) { 597 | type args struct { 598 | a []uint64 599 | } 600 | tests := []struct { 601 | name string 602 | args args 603 | want uint64 604 | wantErr bool 605 | }{ 606 | { 607 | name: "nil slice", 608 | args: args{ 609 | a: nil, 610 | }, 611 | want: 0, 612 | wantErr: true, 613 | }, 614 | { 615 | name: "empty slice", 616 | args: args{ 617 | a: []uint64{}, 618 | }, 619 | want: 0, 620 | wantErr: true, 621 | }, 622 | { 623 | name: "non empty slice", 624 | args: args{ 625 | a: []uint64{1, 4, 5, 34, 2, 100}, 626 | }, 627 | want: 100, 628 | wantErr: false, 629 | }, 630 | } 631 | for _, tt := range tests { 632 | t.Run(tt.name, func(t *testing.T) { 633 | got, err := MaxUint64(tt.args.a) 634 | if (err != nil) != tt.wantErr { 635 | t.Errorf("MaxUint64() error = %v, wantErr %v", err, tt.wantErr) 636 | return 637 | } 638 | if got != tt.want { 639 | t.Errorf("MaxUint64() = %v, want %v", got, tt.want) 640 | } 641 | }) 642 | } 643 | } 644 | 645 | func TestMaxUint8(t *testing.T) { 646 | type args struct { 647 | a []uint8 648 | } 649 | tests := []struct { 650 | name string 651 | args args 652 | want uint8 653 | wantErr bool 654 | }{ 655 | { 656 | name: "nil slice", 657 | args: args{ 658 | a: nil, 659 | }, 660 | want: 0, 661 | wantErr: true, 662 | }, 663 | { 664 | name: "empty slice", 665 | args: args{ 666 | a: []uint8{}, 667 | }, 668 | want: 0, 669 | wantErr: true, 670 | }, 671 | { 672 | name: "non empty slice", 673 | args: args{ 674 | a: []uint8{1, 4, 5, 34, 2, 100}, 675 | }, 676 | want: 100, 677 | wantErr: false, 678 | }, 679 | } 680 | for _, tt := range tests { 681 | t.Run(tt.name, func(t *testing.T) { 682 | got, err := MaxUint8(tt.args.a) 683 | if (err != nil) != tt.wantErr { 684 | t.Errorf("MaxUint8() error = %v, wantErr %v", err, tt.wantErr) 685 | return 686 | } 687 | if got != tt.want { 688 | t.Errorf("MaxUint8() = %v, want %v", got, tt.want) 689 | } 690 | }) 691 | } 692 | } 693 | 694 | func TestMaxUintptr(t *testing.T) { 695 | type args struct { 696 | a []uintptr 697 | } 698 | tests := []struct { 699 | name string 700 | args args 701 | want uintptr 702 | wantErr bool 703 | }{ 704 | { 705 | name: "nil slice", 706 | args: args{ 707 | a: nil, 708 | }, 709 | want: 0, 710 | wantErr: true, 711 | }, 712 | { 713 | name: "empty slice", 714 | args: args{ 715 | a: []uintptr{}, 716 | }, 717 | want: 0, 718 | wantErr: true, 719 | }, 720 | { 721 | name: "non empty slice", 722 | args: args{ 723 | a: []uintptr{1, 4, 5, 34, 2, 100}, 724 | }, 725 | want: 100, 726 | wantErr: false, 727 | }, 728 | } 729 | for _, tt := range tests { 730 | t.Run(tt.name, func(t *testing.T) { 731 | got, err := MaxUintptr(tt.args.a) 732 | if (err != nil) != tt.wantErr { 733 | t.Errorf("MaxUintptr() error = %v, wantErr %v", err, tt.wantErr) 734 | return 735 | } 736 | if got != tt.want { 737 | t.Errorf("MaxUintptr() = %v, want %v", got, tt.want) 738 | } 739 | }) 740 | } 741 | } 742 | 743 | func ExampleMaxInt() { 744 | a := []int{1, 2, 3, 0, 7, 5, 2} 745 | max, err := MaxInt(a) 746 | fmt.Printf("%d, %v", max, err) 747 | // Output: 7, 748 | } 749 | -------------------------------------------------------------------------------- /min.go: -------------------------------------------------------------------------------- 1 | // Package slice provides typesafe functions for common Go slice operations. 2 | package slice 3 | 4 | import "errors" 5 | 6 | // MinByte returns the minimum value of a byte slice or an error in case of a nil or empty slice 7 | func MinByte(a []byte) (byte, error) { 8 | if len(a) == 0 { 9 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 10 | } 11 | 12 | min := a[0] 13 | for k := 1; k < len(a); k++ { 14 | if a[k] < min { 15 | min = a[k] 16 | } 17 | } 18 | 19 | return min, nil 20 | } 21 | 22 | // MinFloat32 returns the minimum value of a float32 slice or an error in case of a nil or empty slice 23 | func MinFloat32(a []float32) (float32, error) { 24 | if len(a) == 0 { 25 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 26 | } 27 | 28 | min := a[0] 29 | for k := 1; k < len(a); k++ { 30 | if a[k] < min { 31 | min = a[k] 32 | } 33 | } 34 | 35 | return min, nil 36 | } 37 | 38 | // MinFloat64 returns the minimum value of a float64 slice or an error in case of a nil or empty slice 39 | func MinFloat64(a []float64) (float64, error) { 40 | if len(a) == 0 { 41 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 42 | } 43 | 44 | min := a[0] 45 | for k := 1; k < len(a); k++ { 46 | if a[k] < min { 47 | min = a[k] 48 | } 49 | } 50 | 51 | return min, nil 52 | } 53 | 54 | // MinInt returns the minimum value of an int slice or an error in case of a nil or empty slice 55 | func MinInt(a []int) (int, error) { 56 | if len(a) == 0 { 57 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 58 | } 59 | 60 | min := a[0] 61 | for k := 1; k < len(a); k++ { 62 | if a[k] < min { 63 | min = a[k] 64 | } 65 | } 66 | 67 | return min, nil 68 | } 69 | 70 | // MinInt8 returns the minimum value of an int8 slice or an error in case of a nil or empty slice 71 | func MinInt8(a []int8) (int8, error) { 72 | if len(a) == 0 { 73 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 74 | } 75 | 76 | min := a[0] 77 | for k := 1; k < len(a); k++ { 78 | if a[k] < min { 79 | min = a[k] 80 | } 81 | } 82 | 83 | return min, nil 84 | } 85 | 86 | // MinInt16 returns the minimum value of an int16 slice or an error in case of a nil or empty slice 87 | func MinInt16(a []int16) (int16, error) { 88 | if len(a) == 0 { 89 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 90 | } 91 | 92 | min := a[0] 93 | for k := 1; k < len(a); k++ { 94 | if a[k] < min { 95 | min = a[k] 96 | } 97 | } 98 | 99 | return min, nil 100 | } 101 | 102 | // MinInt32 returns the minimum value of an int32 slice or an error in case of a nil or empty slice 103 | func MinInt32(a []int32) (int32, error) { 104 | if len(a) == 0 { 105 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 106 | } 107 | 108 | min := a[0] 109 | for k := 1; k < len(a); k++ { 110 | if a[k] < min { 111 | min = a[k] 112 | } 113 | } 114 | 115 | return min, nil 116 | } 117 | 118 | // MinInt64 returns the minimum value of an int64 slice or an error in case of a nil or empty slice 119 | func MinInt64(a []int64) (int64, error) { 120 | if len(a) == 0 { 121 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 122 | } 123 | 124 | min := a[0] 125 | for k := 1; k < len(a); k++ { 126 | if a[k] < min { 127 | min = a[k] 128 | } 129 | } 130 | 131 | return min, nil 132 | } 133 | 134 | // MinRune returns the minimum value of a rune slice or an error in case of a nil or empty slice 135 | func MinRune(a []rune) (rune, error) { 136 | if len(a) == 0 { 137 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 138 | } 139 | 140 | min := a[0] 141 | for k := 1; k < len(a); k++ { 142 | if a[k] < min { 143 | min = a[k] 144 | } 145 | } 146 | 147 | return min, nil 148 | } 149 | 150 | // MinUint returns the minimum value of a uint slice or an error in case of a nil or empty slice 151 | func MinUint(a []uint) (uint, error) { 152 | if len(a) == 0 { 153 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 154 | } 155 | 156 | min := a[0] 157 | for k := 1; k < len(a); k++ { 158 | if a[k] < min { 159 | min = a[k] 160 | } 161 | } 162 | 163 | return min, nil 164 | } 165 | 166 | // MinUint8 returns the minimum value of a uint8 slice or an error in case of a nil or empty slice 167 | func MinUint8(a []uint8) (uint8, error) { 168 | if len(a) == 0 { 169 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 170 | } 171 | 172 | min := a[0] 173 | for k := 1; k < len(a); k++ { 174 | if a[k] < min { 175 | min = a[k] 176 | } 177 | } 178 | 179 | return min, nil 180 | } 181 | 182 | // MinUint16 returns the minimum value of a uint16 slice or an error in case of a nil or empty slice 183 | func MinUint16(a []uint16) (uint16, error) { 184 | if len(a) == 0 { 185 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 186 | } 187 | 188 | min := a[0] 189 | for k := 1; k < len(a); k++ { 190 | if a[k] < min { 191 | min = a[k] 192 | } 193 | } 194 | 195 | return min, nil 196 | } 197 | 198 | // MinUint32 returns the minimum value of a uint32 slice or an error in case of a nil or empty slice 199 | func MinUint32(a []uint32) (uint32, error) { 200 | if len(a) == 0 { 201 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 202 | } 203 | 204 | min := a[0] 205 | for k := 1; k < len(a); k++ { 206 | if a[k] < min { 207 | min = a[k] 208 | } 209 | } 210 | 211 | return min, nil 212 | } 213 | 214 | // MinUint64 returns the minimum value of a uint64 slice or an error in case of a nil or empty slice 215 | func MinUint64(a []uint64) (uint64, error) { 216 | if len(a) == 0 { 217 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 218 | } 219 | 220 | min := a[0] 221 | for k := 1; k < len(a); k++ { 222 | if a[k] < min { 223 | min = a[k] 224 | } 225 | } 226 | 227 | return min, nil 228 | } 229 | 230 | // MinUintptr returns the minimum value of a uintptr slice or an error in case of a nil or empty slice 231 | func MinUintptr(a []uintptr) (uintptr, error) { 232 | if len(a) == 0 { 233 | return 0, errors.New("Cannot get the minimum of a nil or empty slice") 234 | } 235 | 236 | min := a[0] 237 | for k := 1; k < len(a); k++ { 238 | if a[k] < min { 239 | min = a[k] 240 | } 241 | } 242 | 243 | return min, nil 244 | } 245 | -------------------------------------------------------------------------------- /min_test.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestMinByte(t *testing.T) { 9 | type args struct { 10 | a []byte 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want byte 16 | wantErr bool 17 | }{ 18 | { 19 | name: "nil slice", 20 | args: args{ 21 | a: nil, 22 | }, 23 | want: 0, 24 | wantErr: true, 25 | }, 26 | { 27 | name: "empty slice", 28 | args: args{ 29 | a: []byte{}, 30 | }, 31 | want: 0, 32 | wantErr: true, 33 | }, 34 | { 35 | name: "non empty slice", 36 | args: args{ 37 | a: []byte{1, 3, 2, 0, 5, 4}, 38 | }, 39 | want: 0, 40 | wantErr: false, 41 | }, 42 | } 43 | for _, tt := range tests { 44 | t.Run(tt.name, func(t *testing.T) { 45 | got, err := MinByte(tt.args.a) 46 | if (err != nil) != tt.wantErr { 47 | t.Errorf("MinByte() error = %v, wantErr %v", err, tt.wantErr) 48 | return 49 | } 50 | if got != tt.want { 51 | t.Errorf("MinByte() = %v, want %v", got, tt.want) 52 | } 53 | }) 54 | } 55 | } 56 | 57 | func TestMinFloat32(t *testing.T) { 58 | type args struct { 59 | a []float32 60 | } 61 | tests := []struct { 62 | name string 63 | args args 64 | want float32 65 | wantErr bool 66 | }{ 67 | { 68 | name: "nil slice", 69 | args: args{ 70 | a: nil, 71 | }, 72 | want: 0, 73 | wantErr: true, 74 | }, 75 | { 76 | name: "empty slice", 77 | args: args{ 78 | a: []float32{}, 79 | }, 80 | want: 0, 81 | wantErr: true, 82 | }, 83 | { 84 | name: "non empty slice", 85 | args: args{ 86 | a: []float32{1.1, 3.3, 2.2, -5.5, 4.4, 6.6}, 87 | }, 88 | want: -5.5, 89 | wantErr: false, 90 | }, 91 | } 92 | for _, tt := range tests { 93 | t.Run(tt.name, func(t *testing.T) { 94 | got, err := MinFloat32(tt.args.a) 95 | if (err != nil) != tt.wantErr { 96 | t.Errorf("MinFloat32() error = %v, wantErr %v", err, tt.wantErr) 97 | return 98 | } 99 | if got != tt.want { 100 | t.Errorf("MinFloat32() = %v, want %v", got, tt.want) 101 | } 102 | }) 103 | } 104 | } 105 | 106 | func TestMinFloat64(t *testing.T) { 107 | type args struct { 108 | a []float64 109 | } 110 | tests := []struct { 111 | name string 112 | args args 113 | want float64 114 | wantErr bool 115 | }{ 116 | { 117 | name: "nil slice", 118 | args: args{ 119 | a: nil, 120 | }, 121 | want: 0, 122 | wantErr: true, 123 | }, 124 | { 125 | name: "empty slice", 126 | args: args{ 127 | a: []float64{}, 128 | }, 129 | want: 0, 130 | wantErr: true, 131 | }, 132 | { 133 | name: "non empty slice", 134 | args: args{ 135 | a: []float64{1.1, 3.3, 2.2, -5.5, 4.4, 6.6}, 136 | }, 137 | want: -5.5, 138 | wantErr: false, 139 | }, 140 | } 141 | for _, tt := range tests { 142 | t.Run(tt.name, func(t *testing.T) { 143 | got, err := MinFloat64(tt.args.a) 144 | if (err != nil) != tt.wantErr { 145 | t.Errorf("MinFloat64() error = %v, wantErr %v", err, tt.wantErr) 146 | return 147 | } 148 | if got != tt.want { 149 | t.Errorf("MinFloat64() = %v, want %v", got, tt.want) 150 | } 151 | }) 152 | } 153 | } 154 | 155 | func TestMinInt(t *testing.T) { 156 | type args struct { 157 | a []int 158 | } 159 | tests := []struct { 160 | name string 161 | args args 162 | want int 163 | wantErr bool 164 | }{ 165 | { 166 | name: "nil slice", 167 | args: args{ 168 | a: nil, 169 | }, 170 | want: 0, 171 | wantErr: true, 172 | }, 173 | { 174 | name: "empty slice", 175 | args: args{ 176 | a: []int{}, 177 | }, 178 | want: 0, 179 | wantErr: true, 180 | }, 181 | { 182 | name: "non empty slice", 183 | args: args{ 184 | a: []int{1, 3, 2, -4, 6, 5}, 185 | }, 186 | want: -4, 187 | wantErr: false, 188 | }, 189 | } 190 | for _, tt := range tests { 191 | t.Run(tt.name, func(t *testing.T) { 192 | got, err := MinInt(tt.args.a) 193 | if (err != nil) != tt.wantErr { 194 | t.Errorf("MinInt() error = %v, wantErr %v", err, tt.wantErr) 195 | return 196 | } 197 | if got != tt.want { 198 | t.Errorf("MinInt() = %v, want %v", got, tt.want) 199 | } 200 | }) 201 | } 202 | } 203 | 204 | func TestMinInt16(t *testing.T) { 205 | type args struct { 206 | a []int16 207 | } 208 | tests := []struct { 209 | name string 210 | args args 211 | want int16 212 | wantErr bool 213 | }{ 214 | { 215 | name: "nil slice", 216 | args: args{ 217 | a: nil, 218 | }, 219 | want: 0, 220 | wantErr: true, 221 | }, 222 | { 223 | name: "empty slice", 224 | args: args{ 225 | a: []int16{}, 226 | }, 227 | want: 0, 228 | wantErr: true, 229 | }, 230 | { 231 | name: "non empty slice", 232 | args: args{ 233 | a: []int16{1, 3, 2, -4, 6, 5}, 234 | }, 235 | want: -4, 236 | wantErr: false, 237 | }, 238 | } 239 | for _, tt := range tests { 240 | t.Run(tt.name, func(t *testing.T) { 241 | got, err := MinInt16(tt.args.a) 242 | if (err != nil) != tt.wantErr { 243 | t.Errorf("MinInt16() error = %v, wantErr %v", err, tt.wantErr) 244 | return 245 | } 246 | if got != tt.want { 247 | t.Errorf("MinInt16() = %v, want %v", got, tt.want) 248 | } 249 | }) 250 | } 251 | } 252 | 253 | func TestMinInt32(t *testing.T) { 254 | type args struct { 255 | a []int32 256 | } 257 | tests := []struct { 258 | name string 259 | args args 260 | want int32 261 | wantErr bool 262 | }{ 263 | { 264 | name: "nil slice", 265 | args: args{ 266 | a: nil, 267 | }, 268 | want: 0, 269 | wantErr: true, 270 | }, 271 | { 272 | name: "empty slice", 273 | args: args{ 274 | a: []int32{}, 275 | }, 276 | want: 0, 277 | wantErr: true, 278 | }, 279 | { 280 | name: "non empty slice", 281 | args: args{ 282 | a: []int32{1, 3, 2, -4, 6, 5}, 283 | }, 284 | want: -4, 285 | wantErr: false, 286 | }, 287 | } 288 | for _, tt := range tests { 289 | t.Run(tt.name, func(t *testing.T) { 290 | got, err := MinInt32(tt.args.a) 291 | if (err != nil) != tt.wantErr { 292 | t.Errorf("MinInt32() error = %v, wantErr %v", err, tt.wantErr) 293 | return 294 | } 295 | if got != tt.want { 296 | t.Errorf("MinInt32() = %v, want %v", got, tt.want) 297 | } 298 | }) 299 | } 300 | } 301 | 302 | func TestMinInt64(t *testing.T) { 303 | type args struct { 304 | a []int64 305 | } 306 | tests := []struct { 307 | name string 308 | args args 309 | want int64 310 | wantErr bool 311 | }{ 312 | { 313 | name: "nil slice", 314 | args: args{ 315 | a: nil, 316 | }, 317 | want: 0, 318 | wantErr: true, 319 | }, 320 | { 321 | name: "empty slice", 322 | args: args{ 323 | a: []int64{}, 324 | }, 325 | want: 0, 326 | wantErr: true, 327 | }, 328 | { 329 | name: "non empty slice", 330 | args: args{ 331 | a: []int64{1, 3, 2, -4, 6, 5}, 332 | }, 333 | want: -4, 334 | wantErr: false, 335 | }, 336 | } 337 | for _, tt := range tests { 338 | t.Run(tt.name, func(t *testing.T) { 339 | got, err := MinInt64(tt.args.a) 340 | if (err != nil) != tt.wantErr { 341 | t.Errorf("MinInt64() error = %v, wantErr %v", err, tt.wantErr) 342 | return 343 | } 344 | if got != tt.want { 345 | t.Errorf("MinInt64() = %v, want %v", got, tt.want) 346 | } 347 | }) 348 | } 349 | } 350 | 351 | func TestMinInt8(t *testing.T) { 352 | type args struct { 353 | a []int8 354 | } 355 | tests := []struct { 356 | name string 357 | args args 358 | want int8 359 | wantErr bool 360 | }{ 361 | { 362 | name: "nil slice", 363 | args: args{ 364 | a: nil, 365 | }, 366 | want: 0, 367 | wantErr: true, 368 | }, 369 | { 370 | name: "empty slice", 371 | args: args{ 372 | a: []int8{}, 373 | }, 374 | want: 0, 375 | wantErr: true, 376 | }, 377 | { 378 | name: "non empty slice", 379 | args: args{ 380 | a: []int8{1, 3, 2, -4, 6, 5}, 381 | }, 382 | want: -4, 383 | wantErr: false, 384 | }, 385 | } 386 | for _, tt := range tests { 387 | t.Run(tt.name, func(t *testing.T) { 388 | got, err := MinInt8(tt.args.a) 389 | if (err != nil) != tt.wantErr { 390 | t.Errorf("MinInt8() error = %v, wantErr %v", err, tt.wantErr) 391 | return 392 | } 393 | if got != tt.want { 394 | t.Errorf("MinInt8() = %v, want %v", got, tt.want) 395 | } 396 | }) 397 | } 398 | } 399 | 400 | func TestMinRune(t *testing.T) { 401 | type args struct { 402 | a []rune 403 | } 404 | tests := []struct { 405 | name string 406 | args args 407 | want rune 408 | wantErr bool 409 | }{ 410 | { 411 | name: "nil slice", 412 | args: args{ 413 | a: nil, 414 | }, 415 | want: 0, 416 | wantErr: true, 417 | }, 418 | { 419 | name: "empty slice", 420 | args: args{ 421 | a: []rune{}, 422 | }, 423 | want: 0, 424 | wantErr: true, 425 | }, 426 | { 427 | name: "non empty slice", 428 | args: args{ 429 | a: []rune{1, 3, 2, 0, 5, 4}, 430 | }, 431 | want: 0, 432 | wantErr: false, 433 | }, 434 | } 435 | for _, tt := range tests { 436 | t.Run(tt.name, func(t *testing.T) { 437 | got, err := MinRune(tt.args.a) 438 | if (err != nil) != tt.wantErr { 439 | t.Errorf("MinRune() error = %v, wantErr %v", err, tt.wantErr) 440 | return 441 | } 442 | if got != tt.want { 443 | t.Errorf("MinRune() = %v, want %v", got, tt.want) 444 | } 445 | }) 446 | } 447 | } 448 | 449 | func TestMinUint(t *testing.T) { 450 | type args struct { 451 | a []uint 452 | } 453 | tests := []struct { 454 | name string 455 | args args 456 | want uint 457 | wantErr bool 458 | }{ 459 | { 460 | name: "nil slice", 461 | args: args{ 462 | a: nil, 463 | }, 464 | want: 0, 465 | wantErr: true, 466 | }, 467 | { 468 | name: "empty slice", 469 | args: args{ 470 | a: []uint{}, 471 | }, 472 | want: 0, 473 | wantErr: true, 474 | }, 475 | { 476 | name: "non empty slice", 477 | args: args{ 478 | a: []uint{1, 3, 2, 0, 5, 4}, 479 | }, 480 | want: 0, 481 | wantErr: false, 482 | }, 483 | } 484 | for _, tt := range tests { 485 | t.Run(tt.name, func(t *testing.T) { 486 | got, err := MinUint(tt.args.a) 487 | if (err != nil) != tt.wantErr { 488 | t.Errorf("MinUint() error = %v, wantErr %v", err, tt.wantErr) 489 | return 490 | } 491 | if got != tt.want { 492 | t.Errorf("MinUint() = %v, want %v", got, tt.want) 493 | } 494 | }) 495 | } 496 | } 497 | 498 | func TestMinUint16(t *testing.T) { 499 | type args struct { 500 | a []uint16 501 | } 502 | tests := []struct { 503 | name string 504 | args args 505 | want uint16 506 | wantErr bool 507 | }{ 508 | { 509 | name: "nil slice", 510 | args: args{ 511 | a: nil, 512 | }, 513 | want: 0, 514 | wantErr: true, 515 | }, 516 | { 517 | name: "empty slice", 518 | args: args{ 519 | a: []uint16{}, 520 | }, 521 | want: 0, 522 | wantErr: true, 523 | }, 524 | { 525 | name: "non empty slice", 526 | args: args{ 527 | a: []uint16{1, 3, 2, 0, 5, 4}, 528 | }, 529 | want: 0, 530 | wantErr: false, 531 | }, 532 | } 533 | for _, tt := range tests { 534 | t.Run(tt.name, func(t *testing.T) { 535 | got, err := MinUint16(tt.args.a) 536 | if (err != nil) != tt.wantErr { 537 | t.Errorf("MinUint16() error = %v, wantErr %v", err, tt.wantErr) 538 | return 539 | } 540 | if got != tt.want { 541 | t.Errorf("MinUint16() = %v, want %v", got, tt.want) 542 | } 543 | }) 544 | } 545 | } 546 | 547 | func TestMinUint32(t *testing.T) { 548 | type args struct { 549 | a []uint32 550 | } 551 | tests := []struct { 552 | name string 553 | args args 554 | want uint32 555 | wantErr bool 556 | }{ 557 | { 558 | name: "nil slice", 559 | args: args{ 560 | a: nil, 561 | }, 562 | want: 0, 563 | wantErr: true, 564 | }, 565 | { 566 | name: "empty slice", 567 | args: args{ 568 | a: []uint32{}, 569 | }, 570 | want: 0, 571 | wantErr: true, 572 | }, 573 | { 574 | name: "non empty slice", 575 | args: args{ 576 | a: []uint32{1, 3, 2, 0, 5, 4}, 577 | }, 578 | want: 0, 579 | wantErr: false, 580 | }, 581 | } 582 | for _, tt := range tests { 583 | t.Run(tt.name, func(t *testing.T) { 584 | got, err := MinUint32(tt.args.a) 585 | if (err != nil) != tt.wantErr { 586 | t.Errorf("MinUint32() error = %v, wantErr %v", err, tt.wantErr) 587 | return 588 | } 589 | if got != tt.want { 590 | t.Errorf("MinUint32() = %v, want %v", got, tt.want) 591 | } 592 | }) 593 | } 594 | } 595 | 596 | func TestMinUint64(t *testing.T) { 597 | type args struct { 598 | a []uint64 599 | } 600 | tests := []struct { 601 | name string 602 | args args 603 | want uint64 604 | wantErr bool 605 | }{ 606 | { 607 | name: "nil slice", 608 | args: args{ 609 | a: nil, 610 | }, 611 | want: 0, 612 | wantErr: true, 613 | }, 614 | { 615 | name: "empty slice", 616 | args: args{ 617 | a: []uint64{}, 618 | }, 619 | want: 0, 620 | wantErr: true, 621 | }, 622 | { 623 | name: "non empty slice", 624 | args: args{ 625 | a: []uint64{1, 3, 2, 0, 5, 4}, 626 | }, 627 | want: 0, 628 | wantErr: false, 629 | }, 630 | } 631 | for _, tt := range tests { 632 | t.Run(tt.name, func(t *testing.T) { 633 | got, err := MinUint64(tt.args.a) 634 | if (err != nil) != tt.wantErr { 635 | t.Errorf("MinUint64() error = %v, wantErr %v", err, tt.wantErr) 636 | return 637 | } 638 | if got != tt.want { 639 | t.Errorf("MinUint64() = %v, want %v", got, tt.want) 640 | } 641 | }) 642 | } 643 | } 644 | 645 | func TestMinUint8(t *testing.T) { 646 | type args struct { 647 | a []uint8 648 | } 649 | tests := []struct { 650 | name string 651 | args args 652 | want uint8 653 | wantErr bool 654 | }{ 655 | { 656 | name: "nil slice", 657 | args: args{ 658 | a: nil, 659 | }, 660 | want: 0, 661 | wantErr: true, 662 | }, 663 | { 664 | name: "empty slice", 665 | args: args{ 666 | a: []uint8{}, 667 | }, 668 | want: 0, 669 | wantErr: true, 670 | }, 671 | { 672 | name: "non empty slice", 673 | args: args{ 674 | a: []uint8{1, 3, 2, 0, 5, 4}, 675 | }, 676 | want: 0, 677 | wantErr: false, 678 | }, 679 | } 680 | for _, tt := range tests { 681 | t.Run(tt.name, func(t *testing.T) { 682 | got, err := MinUint8(tt.args.a) 683 | if (err != nil) != tt.wantErr { 684 | t.Errorf("MinUint8() error = %v, wantErr %v", err, tt.wantErr) 685 | return 686 | } 687 | if got != tt.want { 688 | t.Errorf("MinUint8() = %v, want %v", got, tt.want) 689 | } 690 | }) 691 | } 692 | } 693 | 694 | func TestMinUintptr(t *testing.T) { 695 | type args struct { 696 | a []uintptr 697 | } 698 | tests := []struct { 699 | name string 700 | args args 701 | want uintptr 702 | wantErr bool 703 | }{ 704 | { 705 | name: "nil slice", 706 | args: args{ 707 | a: nil, 708 | }, 709 | want: 0, 710 | wantErr: true, 711 | }, 712 | { 713 | name: "empty slice", 714 | args: args{ 715 | a: []uintptr{}, 716 | }, 717 | want: 0, 718 | wantErr: true, 719 | }, 720 | { 721 | name: "non empty slice", 722 | args: args{ 723 | a: []uintptr{1, 3, 2, 0, 5, 4}, 724 | }, 725 | want: 0, 726 | wantErr: false, 727 | }, 728 | } 729 | for _, tt := range tests { 730 | t.Run(tt.name, func(t *testing.T) { 731 | got, err := MinUintptr(tt.args.a) 732 | if (err != nil) != tt.wantErr { 733 | t.Errorf("MinUintptr() error = %v, wantErr %v", err, tt.wantErr) 734 | return 735 | } 736 | if got != tt.want { 737 | t.Errorf("MinUintptr() = %v, want %v", got, tt.want) 738 | } 739 | }) 740 | } 741 | } 742 | 743 | func ExampleMinInt() { 744 | a := []int{1, 2, 3, 0, 7, 5, 2} 745 | min, err := MinInt(a) 746 | fmt.Printf("%d, %v", min, err) 747 | // Output: 0, 748 | } 749 | -------------------------------------------------------------------------------- /pop.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import "errors" 4 | 5 | // PopBool removes and returns the last value a bool slice and the remaining slice. 6 | // An error is returned in case of a nil or empty slice. 7 | func PopBool(a []bool) (bool, []bool, error) { 8 | if len(a) == 0 { 9 | return false, nil, errors.New("Cannot pop from a nil or empty slice") 10 | } 11 | 12 | return a[len(a)-1], a[:len(a)-1], nil 13 | } 14 | 15 | // PopByte removes and returns the last value a byte slice and the remaining slice. 16 | // An error is returned in case of a nil or empty slice. 17 | func PopByte(a []byte) (byte, []byte, error) { 18 | if len(a) == 0 { 19 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 20 | } 21 | 22 | return a[len(a)-1], a[:len(a)-1], nil 23 | } 24 | 25 | // PopComplex128 removes and returns the last value a complex128 slice and the remaining slice. 26 | // An error is returned in case of a nil or empty slice. 27 | func PopComplex128(a []complex128) (complex128, []complex128, error) { 28 | if len(a) == 0 { 29 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 30 | } 31 | 32 | return a[len(a)-1], a[:len(a)-1], nil 33 | } 34 | 35 | // PopComplex64 removes and returns the last value a complex64 slice and the remaining slice. 36 | // An error is returned in case of a nil or empty slice. 37 | func PopComplex64(a []complex64) (complex64, []complex64, error) { 38 | if len(a) == 0 { 39 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 40 | } 41 | 42 | return a[len(a)-1], a[:len(a)-1], nil 43 | } 44 | 45 | // PopFloat32 removes and returns the last value a float32 slice and the remaining slice. 46 | // An error is returned in case of a nil or empty slice. 47 | func PopFloat32(a []float32) (float32, []float32, error) { 48 | if len(a) == 0 { 49 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 50 | } 51 | 52 | return a[len(a)-1], a[:len(a)-1], nil 53 | } 54 | 55 | // PopFloat64 removes and returns the last value a float64 slice and the remaining slice. 56 | // An error is returned in case of a nil or empty slice. 57 | func PopFloat64(a []float64) (float64, []float64, error) { 58 | if len(a) == 0 { 59 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 60 | } 61 | 62 | return a[len(a)-1], a[:len(a)-1], nil 63 | } 64 | 65 | // PopInt removes and returns the last value a int slice and the remaining slice. 66 | // An error is returned in case of a nil or empty slice. 67 | func PopInt(a []int) (int, []int, error) { 68 | if len(a) == 0 { 69 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 70 | } 71 | 72 | return a[len(a)-1], a[:len(a)-1], nil 73 | } 74 | 75 | // PopInt16 removes and returns the last value a int16 slice and the remaining slice. 76 | // An error is returned in case of a nil or empty slice. 77 | func PopInt16(a []int16) (int16, []int16, error) { 78 | if len(a) == 0 { 79 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 80 | } 81 | 82 | return a[len(a)-1], a[:len(a)-1], nil 83 | } 84 | 85 | // PopInt32 removes and returns the last value a int32 slice and the remaining slice. 86 | // An error is returned in case of a nil or empty slice. 87 | func PopInt32(a []int32) (int32, []int32, error) { 88 | if len(a) == 0 { 89 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 90 | } 91 | 92 | return a[len(a)-1], a[:len(a)-1], nil 93 | } 94 | 95 | // PopInt64 removes and returns the last value a int64 slice and the remaining slice. 96 | // An error is returned in case of a nil or empty slice. 97 | func PopInt64(a []int64) (int64, []int64, error) { 98 | if len(a) == 0 { 99 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 100 | } 101 | 102 | return a[len(a)-1], a[:len(a)-1], nil 103 | } 104 | 105 | // PopInt8 removes and returns the last value a int8 slice and the remaining slice. 106 | // An error is returned in case of a nil or empty slice. 107 | func PopInt8(a []int8) (int8, []int8, error) { 108 | if len(a) == 0 { 109 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 110 | } 111 | 112 | return a[len(a)-1], a[:len(a)-1], nil 113 | } 114 | 115 | // PopRune removes and returns the last value a rune slice and the remaining slice. 116 | // An error is returned in case of a nil or empty slice. 117 | func PopRune(a []rune) (rune, []rune, error) { 118 | if len(a) == 0 { 119 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 120 | } 121 | 122 | return a[len(a)-1], a[:len(a)-1], nil 123 | } 124 | 125 | // PopString removes and returns the last value a string slice and the remaining slice. 126 | // An error is returned in case of a nil or empty slice. 127 | func PopString(a []string) (string, []string, error) { 128 | if len(a) == 0 { 129 | return "", nil, errors.New("Cannot pop from a nil or empty slice") 130 | } 131 | 132 | return a[len(a)-1], a[:len(a)-1], nil 133 | } 134 | 135 | // PopUint removes and returns the last value a uint slice and the remaining slice. 136 | // An error is returned in case of a nil or empty slice. 137 | func PopUint(a []uint) (uint, []uint, error) { 138 | if len(a) == 0 { 139 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 140 | } 141 | 142 | return a[len(a)-1], a[:len(a)-1], nil 143 | } 144 | 145 | // PopUint16 removes and returns the last value a uint16 slice and the remaining slice. 146 | // An error is returned in case of a nil or empty slice. 147 | func PopUint16(a []uint16) (uint16, []uint16, error) { 148 | if len(a) == 0 { 149 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 150 | } 151 | 152 | return a[len(a)-1], a[:len(a)-1], nil 153 | } 154 | 155 | // PopUint32 removes and returns the last value a uint32 slice and the remaining slice. 156 | // An error is returned in case of a nil or empty slice. 157 | func PopUint32(a []uint32) (uint32, []uint32, error) { 158 | if len(a) == 0 { 159 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 160 | } 161 | 162 | return a[len(a)-1], a[:len(a)-1], nil 163 | } 164 | 165 | // PopUint64 removes and returns the last value a uint64 slice and the remaining slice. 166 | // An error is returned in case of a nil or empty slice. 167 | func PopUint64(a []uint64) (uint64, []uint64, error) { 168 | if len(a) == 0 { 169 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 170 | } 171 | 172 | return a[len(a)-1], a[:len(a)-1], nil 173 | } 174 | 175 | // PopUint8 removes and returns the last value a uint8 slice and the remaining slice. 176 | // An error is returned in case of a nil or empty slice. 177 | func PopUint8(a []uint8) (uint8, []uint8, error) { 178 | if len(a) == 0 { 179 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 180 | } 181 | 182 | return a[len(a)-1], a[:len(a)-1], nil 183 | } 184 | 185 | // PopUintptr removes and returns the last value a uintptr slice and the remaining slice. 186 | // An error is returned in case of a nil or empty slice. 187 | func PopUintptr(a []uintptr) (uintptr, []uintptr, error) { 188 | if len(a) == 0 { 189 | return 0, nil, errors.New("Cannot pop from a nil or empty slice") 190 | } 191 | 192 | return a[len(a)-1], a[:len(a)-1], nil 193 | } 194 | -------------------------------------------------------------------------------- /reverse.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | // ReverseBool performs in place reversal of a bool slice 4 | func ReverseBool(a []bool) []bool { 5 | if len(a) == 0 { 6 | return a 7 | } 8 | 9 | s, e := 0, len(a)-1 10 | for s < e { 11 | a[s], a[e] = a[e], a[s] 12 | s++ 13 | e-- 14 | } 15 | 16 | return a 17 | } 18 | 19 | // ReverseByte performs in place reversal of a byte slice 20 | func ReverseByte(a []byte) []byte { 21 | if len(a) == 0 { 22 | return a 23 | } 24 | 25 | s, e := 0, len(a)-1 26 | for s < e { 27 | a[s], a[e] = a[e], a[s] 28 | s++ 29 | e-- 30 | } 31 | 32 | return a 33 | } 34 | 35 | // ReverseComplex128 performs in place reversal of a complex128 slice 36 | func ReverseComplex128(a []complex128) []complex128 { 37 | if len(a) == 0 { 38 | return a 39 | } 40 | 41 | s, e := 0, len(a)-1 42 | for s < e { 43 | a[s], a[e] = a[e], a[s] 44 | s++ 45 | e-- 46 | } 47 | 48 | return a 49 | } 50 | 51 | // ReverseComplex64 performs in place reversal of a complex64 slice 52 | func ReverseComplex64(a []complex64) []complex64 { 53 | if len(a) == 0 { 54 | return a 55 | } 56 | 57 | s, e := 0, len(a)-1 58 | for s < e { 59 | a[s], a[e] = a[e], a[s] 60 | s++ 61 | e-- 62 | } 63 | 64 | return a 65 | } 66 | 67 | // ReverseFloat32 performs in place reversal of a float32 slice 68 | func ReverseFloat32(a []float32) []float32 { 69 | if len(a) == 0 { 70 | return a 71 | } 72 | 73 | s, e := 0, len(a)-1 74 | for s < e { 75 | a[s], a[e] = a[e], a[s] 76 | s++ 77 | e-- 78 | } 79 | 80 | return a 81 | } 82 | 83 | // ReverseFloat64 performs in place reversal of a float64 slice 84 | func ReverseFloat64(a []float64) []float64 { 85 | if len(a) == 0 { 86 | return a 87 | } 88 | 89 | s, e := 0, len(a)-1 90 | for s < e { 91 | a[s], a[e] = a[e], a[s] 92 | s++ 93 | e-- 94 | } 95 | 96 | return a 97 | } 98 | 99 | // ReverseInt performs in place reversal of an int slice 100 | func ReverseInt(a []int) []int { 101 | if len(a) == 0 { 102 | return a 103 | } 104 | 105 | s, e := 0, len(a)-1 106 | for s < e { 107 | a[s], a[e] = a[e], a[s] 108 | s++ 109 | e-- 110 | } 111 | 112 | return a 113 | } 114 | 115 | // ReverseInt16 performs in place reversal of an int16 slice 116 | func ReverseInt16(a []int16) []int16 { 117 | if len(a) == 0 { 118 | return a 119 | } 120 | 121 | s, e := 0, len(a)-1 122 | for s < e { 123 | a[s], a[e] = a[e], a[s] 124 | s++ 125 | e-- 126 | } 127 | 128 | return a 129 | } 130 | 131 | // ReverseInt32 performs in place reversal of an int32 slice 132 | func ReverseInt32(a []int32) []int32 { 133 | if len(a) == 0 { 134 | return a 135 | } 136 | 137 | s, e := 0, len(a)-1 138 | for s < e { 139 | a[s], a[e] = a[e], a[s] 140 | s++ 141 | e-- 142 | } 143 | 144 | return a 145 | } 146 | 147 | // ReverseInt64 performs in place reversal of an int64 slice 148 | func ReverseInt64(a []int64) []int64 { 149 | if len(a) == 0 { 150 | return a 151 | } 152 | 153 | s, e := 0, len(a)-1 154 | for s < e { 155 | a[s], a[e] = a[e], a[s] 156 | s++ 157 | e-- 158 | } 159 | 160 | return a 161 | } 162 | 163 | // ReverseInt8 performs in place reversal of an int8 slice 164 | func ReverseInt8(a []int8) []int8 { 165 | if len(a) == 0 { 166 | return a 167 | } 168 | 169 | s, e := 0, len(a)-1 170 | for s < e { 171 | a[s], a[e] = a[e], a[s] 172 | s++ 173 | e-- 174 | } 175 | 176 | return a 177 | } 178 | 179 | // ReverseRune performs in place reversal of a rune slice 180 | func ReverseRune(a []rune) []rune { 181 | if len(a) == 0 { 182 | return a 183 | } 184 | 185 | s, e := 0, len(a)-1 186 | for s < e { 187 | a[s], a[e] = a[e], a[s] 188 | s++ 189 | e-- 190 | } 191 | 192 | return a 193 | } 194 | 195 | // ReverseString performs in place reversal of a string slice 196 | func ReverseString(a []string) []string { 197 | if len(a) == 0 { 198 | return a 199 | } 200 | 201 | s, e := 0, len(a)-1 202 | for s < e { 203 | a[s], a[e] = a[e], a[s] 204 | s++ 205 | e-- 206 | } 207 | 208 | return a 209 | } 210 | 211 | // ReverseUint performs in place reversal of a uint slice 212 | func ReverseUint(a []uint) []uint { 213 | if len(a) == 0 { 214 | return a 215 | } 216 | 217 | s, e := 0, len(a)-1 218 | for s < e { 219 | a[s], a[e] = a[e], a[s] 220 | s++ 221 | e-- 222 | } 223 | 224 | return a 225 | } 226 | 227 | // ReverseUint16 performs in place reversal of a uint16 slice 228 | func ReverseUint16(a []uint16) []uint16 { 229 | if len(a) == 0 { 230 | return a 231 | } 232 | 233 | s, e := 0, len(a)-1 234 | for s < e { 235 | a[s], a[e] = a[e], a[s] 236 | s++ 237 | e-- 238 | } 239 | 240 | return a 241 | } 242 | 243 | // ReverseUint32 performs in place reversal of a uint32 slice 244 | func ReverseUint32(a []uint32) []uint32 { 245 | if len(a) == 0 { 246 | return a 247 | } 248 | 249 | s, e := 0, len(a)-1 250 | for s < e { 251 | a[s], a[e] = a[e], a[s] 252 | s++ 253 | e-- 254 | } 255 | 256 | return a 257 | } 258 | 259 | // ReverseUint64 performs in place reversal of a uint64 slice 260 | func ReverseUint64(a []uint64) []uint64 { 261 | if len(a) == 0 { 262 | return a 263 | } 264 | 265 | s, e := 0, len(a)-1 266 | for s < e { 267 | a[s], a[e] = a[e], a[s] 268 | s++ 269 | e-- 270 | } 271 | 272 | return a 273 | } 274 | 275 | // ReverseUint8 performs in place reversal of a uint8 slice 276 | func ReverseUint8(a []uint8) []uint8 { 277 | if len(a) == 0 { 278 | return a 279 | } 280 | 281 | s, e := 0, len(a)-1 282 | for s < e { 283 | a[s], a[e] = a[e], a[s] 284 | s++ 285 | e-- 286 | } 287 | 288 | return a 289 | } 290 | 291 | // ReverseUintptr performs in place reversal of a uintptr slice 292 | func ReverseUintptr(a []uintptr) []uintptr { 293 | if len(a) == 0 { 294 | return a 295 | } 296 | 297 | s, e := 0, len(a)-1 298 | for s < e { 299 | a[s], a[e] = a[e], a[s] 300 | s++ 301 | e-- 302 | } 303 | 304 | return a 305 | } 306 | -------------------------------------------------------------------------------- /reverse_test.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestReverseBool(t *testing.T) { 10 | type args struct { 11 | src []bool 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []bool 17 | }{ 18 | { 19 | name: "nil slice", 20 | args: args{ 21 | src: nil, 22 | }, 23 | want: nil, 24 | }, 25 | { 26 | name: "empty slice", 27 | args: args{ 28 | src: []bool{}, 29 | }, 30 | want: []bool{}, 31 | }, 32 | { 33 | name: "slice odd elements", 34 | args: args{ 35 | src: []bool{true, true, true, false, false}, 36 | }, 37 | want: []bool{false, false, true, true, true}, 38 | }, 39 | { 40 | name: "slice with even elements", 41 | args: args{ 42 | src: []bool{true, true, false, false}, 43 | }, 44 | want: []bool{false, false, true, true}, 45 | }, 46 | } 47 | for _, tt := range tests { 48 | t.Run(tt.name, func(t *testing.T) { 49 | if got := ReverseBool(tt.args.src); !reflect.DeepEqual(got, tt.want) { 50 | t.Errorf("ReverseBool() = %v, want %v", got, tt.want) 51 | } 52 | }) 53 | } 54 | } 55 | 56 | func TestReverseByte(t *testing.T) { 57 | type args struct { 58 | src []byte 59 | } 60 | tests := []struct { 61 | name string 62 | args args 63 | want []byte 64 | }{ 65 | { 66 | name: "nil slice", 67 | args: args{ 68 | src: nil, 69 | }, 70 | want: nil, 71 | }, 72 | { 73 | name: "empty slice", 74 | args: args{ 75 | src: []byte{}, 76 | }, 77 | want: []byte{}, 78 | }, 79 | { 80 | name: "slice odd elements", 81 | args: args{ 82 | src: []byte{1, 2, 3, 4, 5}, 83 | }, 84 | want: []byte{5, 4, 3, 2, 1}, 85 | }, 86 | { 87 | name: "slice with even elements", 88 | args: args{ 89 | src: []byte{1, 2, 3, 4}, 90 | }, 91 | want: []byte{4, 3, 2, 1}, 92 | }, 93 | } 94 | for _, tt := range tests { 95 | t.Run(tt.name, func(t *testing.T) { 96 | if got := ReverseByte(tt.args.src); !reflect.DeepEqual(got, tt.want) { 97 | t.Errorf("ReverseByte() = %v, want %v", got, tt.want) 98 | } 99 | }) 100 | } 101 | } 102 | 103 | func TestReverseComplex128(t *testing.T) { 104 | type args struct { 105 | src []complex128 106 | } 107 | tests := []struct { 108 | name string 109 | args args 110 | want []complex128 111 | }{ 112 | { 113 | name: "nil slice", 114 | args: args{ 115 | src: nil, 116 | }, 117 | want: nil, 118 | }, 119 | { 120 | name: "empty slice", 121 | args: args{ 122 | src: []complex128{}, 123 | }, 124 | want: []complex128{}, 125 | }, 126 | { 127 | name: "slice odd elements", 128 | args: args{ 129 | src: []complex128{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4), complex(5, 5)}, 130 | }, 131 | want: []complex128{complex(5, 5), complex(4, 4), complex(3, 3), complex(2, 2), complex(1, 1)}, 132 | }, 133 | { 134 | name: "slice with even elements", 135 | args: args{ 136 | src: []complex128{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4)}, 137 | }, 138 | want: []complex128{complex(4, 4), complex(3, 3), complex(2, 2), complex(1, 1)}, 139 | }, 140 | } 141 | for _, tt := range tests { 142 | t.Run(tt.name, func(t *testing.T) { 143 | if got := ReverseComplex128(tt.args.src); !reflect.DeepEqual(got, tt.want) { 144 | t.Errorf("ReverseComplex128() = %v, want %v", got, tt.want) 145 | } 146 | }) 147 | } 148 | } 149 | 150 | func TestReverseComplex64(t *testing.T) { 151 | type args struct { 152 | src []complex64 153 | } 154 | tests := []struct { 155 | name string 156 | args args 157 | want []complex64 158 | }{ 159 | { 160 | name: "nil slice", 161 | args: args{ 162 | src: nil, 163 | }, 164 | want: nil, 165 | }, 166 | { 167 | name: "empty slice", 168 | args: args{ 169 | src: []complex64{}, 170 | }, 171 | want: []complex64{}, 172 | }, 173 | { 174 | name: "slice odd elements", 175 | args: args{ 176 | src: []complex64{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4), complex(5, 5)}, 177 | }, 178 | want: []complex64{complex(5, 5), complex(4, 4), complex(3, 3), complex(2, 2), complex(1, 1)}, 179 | }, 180 | { 181 | name: "slice with even elements", 182 | args: args{ 183 | src: []complex64{complex(1, 1), complex(2, 2), complex(3, 3), complex(4, 4)}, 184 | }, 185 | want: []complex64{complex(4, 4), complex(3, 3), complex(2, 2), complex(1, 1)}, 186 | }, 187 | } 188 | for _, tt := range tests { 189 | t.Run(tt.name, func(t *testing.T) { 190 | if got := ReverseComplex64(tt.args.src); !reflect.DeepEqual(got, tt.want) { 191 | t.Errorf("ReverseComplex64() = %v, want %v", got, tt.want) 192 | } 193 | }) 194 | } 195 | } 196 | 197 | func TestReverseFloat32(t *testing.T) { 198 | type args struct { 199 | src []float32 200 | } 201 | tests := []struct { 202 | name string 203 | args args 204 | want []float32 205 | }{ 206 | { 207 | name: "nil slice", 208 | args: args{ 209 | src: nil, 210 | }, 211 | want: nil, 212 | }, 213 | { 214 | name: "empty slice", 215 | args: args{ 216 | src: []float32{}, 217 | }, 218 | want: []float32{}, 219 | }, 220 | { 221 | name: "slice odd elements", 222 | args: args{ 223 | src: []float32{1.1, 2.2, 3.3, 4.4, 5.5}, 224 | }, 225 | want: []float32{5.5, 4.4, 3.3, 2.2, 1.1}, 226 | }, 227 | { 228 | name: "slice with even elements", 229 | args: args{ 230 | src: []float32{1.1, 2.2, 3.3, 4.4}, 231 | }, 232 | want: []float32{4.4, 3.3, 2.2, 1.1}, 233 | }, 234 | } 235 | for _, tt := range tests { 236 | t.Run(tt.name, func(t *testing.T) { 237 | if got := ReverseFloat32(tt.args.src); !reflect.DeepEqual(got, tt.want) { 238 | t.Errorf("ReverseFloat32() = %v, want %v", got, tt.want) 239 | } 240 | }) 241 | } 242 | } 243 | 244 | func TestReverseFloat64(t *testing.T) { 245 | type args struct { 246 | src []float64 247 | } 248 | tests := []struct { 249 | name string 250 | args args 251 | want []float64 252 | }{ 253 | { 254 | name: "nil slice", 255 | args: args{ 256 | src: nil, 257 | }, 258 | want: nil, 259 | }, 260 | { 261 | name: "empty slice", 262 | args: args{ 263 | src: []float64{}, 264 | }, 265 | want: []float64{}, 266 | }, 267 | { 268 | name: "slice odd elements", 269 | args: args{ 270 | src: []float64{1.1, 2.2, 3.3, 4.4, 5.5}, 271 | }, 272 | want: []float64{5.5, 4.4, 3.3, 2.2, 1.1}, 273 | }, 274 | { 275 | name: "slice with even elements", 276 | args: args{ 277 | src: []float64{1.1, 2.2, 3.3, 4.4}, 278 | }, 279 | want: []float64{4.4, 3.3, 2.2, 1.1}, 280 | }, 281 | } 282 | for _, tt := range tests { 283 | t.Run(tt.name, func(t *testing.T) { 284 | if got := ReverseFloat64(tt.args.src); !reflect.DeepEqual(got, tt.want) { 285 | t.Errorf("ReverseFloat64() = %v, want %v", got, tt.want) 286 | } 287 | }) 288 | } 289 | } 290 | 291 | func TestReverseInt(t *testing.T) { 292 | type args struct { 293 | src []int 294 | } 295 | tests := []struct { 296 | name string 297 | args args 298 | want []int 299 | }{ 300 | { 301 | name: "nil slice", 302 | args: args{ 303 | src: nil, 304 | }, 305 | want: nil, 306 | }, 307 | { 308 | name: "empty slice", 309 | args: args{ 310 | src: []int{}, 311 | }, 312 | want: []int{}, 313 | }, 314 | { 315 | name: "slice odd elements", 316 | args: args{ 317 | src: []int{1, 2, 3, 4, 5}, 318 | }, 319 | want: []int{5, 4, 3, 2, 1}, 320 | }, 321 | { 322 | name: "slice with even elements", 323 | args: args{ 324 | src: []int{1, 2, 3, 4}, 325 | }, 326 | want: []int{4, 3, 2, 1}, 327 | }, 328 | } 329 | for _, tt := range tests { 330 | t.Run(tt.name, func(t *testing.T) { 331 | if got := ReverseInt(tt.args.src); !reflect.DeepEqual(got, tt.want) { 332 | t.Errorf("ReverseInt() = %v, want %v", got, tt.want) 333 | } 334 | }) 335 | } 336 | } 337 | 338 | func TestReverseInt16(t *testing.T) { 339 | type args struct { 340 | src []int16 341 | } 342 | tests := []struct { 343 | name string 344 | args args 345 | want []int16 346 | }{ 347 | { 348 | name: "nil slice", 349 | args: args{ 350 | src: nil, 351 | }, 352 | want: nil, 353 | }, 354 | { 355 | name: "empty slice", 356 | args: args{ 357 | src: []int16{}, 358 | }, 359 | want: []int16{}, 360 | }, 361 | { 362 | name: "slice odd elements", 363 | args: args{ 364 | src: []int16{1, 2, 3, 4, 5}, 365 | }, 366 | want: []int16{5, 4, 3, 2, 1}, 367 | }, 368 | { 369 | name: "slice with even elements", 370 | args: args{ 371 | src: []int16{1, 2, 3, 4}, 372 | }, 373 | want: []int16{4, 3, 2, 1}, 374 | }, 375 | } 376 | for _, tt := range tests { 377 | t.Run(tt.name, func(t *testing.T) { 378 | if got := ReverseInt16(tt.args.src); !reflect.DeepEqual(got, tt.want) { 379 | t.Errorf("ReverseInt16() = %v, want %v", got, tt.want) 380 | } 381 | }) 382 | } 383 | } 384 | 385 | func TestReverseInt32(t *testing.T) { 386 | type args struct { 387 | src []int32 388 | } 389 | tests := []struct { 390 | name string 391 | args args 392 | want []int32 393 | }{ 394 | { 395 | name: "nil slice", 396 | args: args{ 397 | src: nil, 398 | }, 399 | want: nil, 400 | }, 401 | { 402 | name: "empty slice", 403 | args: args{ 404 | src: []int32{}, 405 | }, 406 | want: []int32{}, 407 | }, 408 | { 409 | name: "slice odd elements", 410 | args: args{ 411 | src: []int32{1, 2, 3, 4, 5}, 412 | }, 413 | want: []int32{5, 4, 3, 2, 1}, 414 | }, 415 | { 416 | name: "slice with even elements", 417 | args: args{ 418 | src: []int32{1, 2, 3, 4}, 419 | }, 420 | want: []int32{4, 3, 2, 1}, 421 | }, 422 | } 423 | for _, tt := range tests { 424 | t.Run(tt.name, func(t *testing.T) { 425 | if got := ReverseInt32(tt.args.src); !reflect.DeepEqual(got, tt.want) { 426 | t.Errorf("ReverseInt32() = %v, want %v", got, tt.want) 427 | } 428 | }) 429 | } 430 | } 431 | 432 | func TestReverseInt64(t *testing.T) { 433 | type args struct { 434 | src []int64 435 | } 436 | tests := []struct { 437 | name string 438 | args args 439 | want []int64 440 | }{ 441 | { 442 | name: "nil slice", 443 | args: args{ 444 | src: nil, 445 | }, 446 | want: nil, 447 | }, 448 | { 449 | name: "empty slice", 450 | args: args{ 451 | src: []int64{}, 452 | }, 453 | want: []int64{}, 454 | }, 455 | { 456 | name: "slice odd elements", 457 | args: args{ 458 | src: []int64{1, 2, 3, 4, 5}, 459 | }, 460 | want: []int64{5, 4, 3, 2, 1}, 461 | }, 462 | { 463 | name: "slice with even elements", 464 | args: args{ 465 | src: []int64{1, 2, 3, 4}, 466 | }, 467 | want: []int64{4, 3, 2, 1}, 468 | }, 469 | } 470 | for _, tt := range tests { 471 | t.Run(tt.name, func(t *testing.T) { 472 | if got := ReverseInt64(tt.args.src); !reflect.DeepEqual(got, tt.want) { 473 | t.Errorf("ReverseInt64() = %v, want %v", got, tt.want) 474 | } 475 | }) 476 | } 477 | } 478 | 479 | func TestReverseInt8(t *testing.T) { 480 | type args struct { 481 | src []int8 482 | } 483 | tests := []struct { 484 | name string 485 | args args 486 | want []int8 487 | }{ 488 | { 489 | name: "nil slice", 490 | args: args{ 491 | src: nil, 492 | }, 493 | want: nil, 494 | }, 495 | { 496 | name: "empty slice", 497 | args: args{ 498 | src: []int8{}, 499 | }, 500 | want: []int8{}, 501 | }, 502 | { 503 | name: "slice odd elements", 504 | args: args{ 505 | src: []int8{1, 2, 3, 4, 5}, 506 | }, 507 | want: []int8{5, 4, 3, 2, 1}, 508 | }, 509 | { 510 | name: "slice with even elements", 511 | args: args{ 512 | src: []int8{1, 2, 3, 4}, 513 | }, 514 | want: []int8{4, 3, 2, 1}, 515 | }, 516 | } 517 | for _, tt := range tests { 518 | t.Run(tt.name, func(t *testing.T) { 519 | if got := ReverseInt8(tt.args.src); !reflect.DeepEqual(got, tt.want) { 520 | t.Errorf("ReverseInt8() = %v, want %v", got, tt.want) 521 | } 522 | }) 523 | } 524 | } 525 | 526 | func TestReverseRune(t *testing.T) { 527 | type args struct { 528 | src []rune 529 | } 530 | tests := []struct { 531 | name string 532 | args args 533 | want []rune 534 | }{ 535 | { 536 | name: "nil slice", 537 | args: args{ 538 | src: nil, 539 | }, 540 | want: nil, 541 | }, 542 | { 543 | name: "empty slice", 544 | args: args{ 545 | src: []rune{}, 546 | }, 547 | want: []rune{}, 548 | }, 549 | { 550 | name: "slice odd elements", 551 | args: args{ 552 | src: []rune{1, 2, 3, 4, 5}, 553 | }, 554 | want: []rune{5, 4, 3, 2, 1}, 555 | }, 556 | { 557 | name: "slice with even elements", 558 | args: args{ 559 | src: []rune{1, 2, 3, 4}, 560 | }, 561 | want: []rune{4, 3, 2, 1}, 562 | }, 563 | } 564 | for _, tt := range tests { 565 | t.Run(tt.name, func(t *testing.T) { 566 | if got := ReverseRune(tt.args.src); !reflect.DeepEqual(got, tt.want) { 567 | t.Errorf("ReverseRune() = %v, want %v", got, tt.want) 568 | } 569 | }) 570 | } 571 | } 572 | 573 | func TestReverseString(t *testing.T) { 574 | type args struct { 575 | src []string 576 | } 577 | tests := []struct { 578 | name string 579 | args args 580 | want []string 581 | }{ 582 | { 583 | name: "nil slice", 584 | args: args{ 585 | src: nil, 586 | }, 587 | want: nil, 588 | }, 589 | { 590 | name: "empty slice", 591 | args: args{ 592 | src: []string{}, 593 | }, 594 | want: []string{}, 595 | }, 596 | { 597 | name: "slice odd elements", 598 | args: args{ 599 | src: []string{"a", "b", "c", "d", "e"}, 600 | }, 601 | want: []string{"e", "d", "c", "b", "a"}, 602 | }, 603 | { 604 | name: "slice with even elements", 605 | args: args{ 606 | src: []string{"a", "b", "c", "d"}, 607 | }, 608 | want: []string{"d", "c", "b", "a"}, 609 | }, 610 | } 611 | for _, tt := range tests { 612 | t.Run(tt.name, func(t *testing.T) { 613 | if got := ReverseString(tt.args.src); !reflect.DeepEqual(got, tt.want) { 614 | t.Errorf("ReverseString() = %v, want %v", got, tt.want) 615 | } 616 | }) 617 | } 618 | } 619 | 620 | func TestReverseUint(t *testing.T) { 621 | type args struct { 622 | src []uint 623 | } 624 | tests := []struct { 625 | name string 626 | args args 627 | want []uint 628 | }{ 629 | { 630 | name: "nil slice", 631 | args: args{ 632 | src: nil, 633 | }, 634 | want: nil, 635 | }, 636 | { 637 | name: "empty slice", 638 | args: args{ 639 | src: []uint{}, 640 | }, 641 | want: []uint{}, 642 | }, 643 | { 644 | name: "slice odd elements", 645 | args: args{ 646 | src: []uint{1, 2, 3, 4, 5}, 647 | }, 648 | want: []uint{5, 4, 3, 2, 1}, 649 | }, 650 | { 651 | name: "slice with even elements", 652 | args: args{ 653 | src: []uint{1, 2, 3, 4}, 654 | }, 655 | want: []uint{4, 3, 2, 1}, 656 | }, 657 | } 658 | for _, tt := range tests { 659 | t.Run(tt.name, func(t *testing.T) { 660 | if got := ReverseUint(tt.args.src); !reflect.DeepEqual(got, tt.want) { 661 | t.Errorf("ReverseUint() = %v, want %v", got, tt.want) 662 | } 663 | }) 664 | } 665 | } 666 | 667 | func TestReverseUint16(t *testing.T) { 668 | type args struct { 669 | src []uint16 670 | } 671 | tests := []struct { 672 | name string 673 | args args 674 | want []uint16 675 | }{ 676 | { 677 | name: "nil slice", 678 | args: args{ 679 | src: nil, 680 | }, 681 | want: nil, 682 | }, 683 | { 684 | name: "empty slice", 685 | args: args{ 686 | src: []uint16{}, 687 | }, 688 | want: []uint16{}, 689 | }, 690 | { 691 | name: "slice odd elements", 692 | args: args{ 693 | src: []uint16{1, 2, 3, 4, 5}, 694 | }, 695 | want: []uint16{5, 4, 3, 2, 1}, 696 | }, 697 | { 698 | name: "slice with even elements", 699 | args: args{ 700 | src: []uint16{1, 2, 3, 4}, 701 | }, 702 | want: []uint16{4, 3, 2, 1}, 703 | }, 704 | } 705 | for _, tt := range tests { 706 | t.Run(tt.name, func(t *testing.T) { 707 | if got := ReverseUint16(tt.args.src); !reflect.DeepEqual(got, tt.want) { 708 | t.Errorf("ReverseUint16() = %v, want %v", got, tt.want) 709 | } 710 | }) 711 | } 712 | } 713 | 714 | func TestReverseUint32(t *testing.T) { 715 | type args struct { 716 | src []uint32 717 | } 718 | tests := []struct { 719 | name string 720 | args args 721 | want []uint32 722 | }{ 723 | { 724 | name: "nil slice", 725 | args: args{ 726 | src: nil, 727 | }, 728 | want: nil, 729 | }, 730 | { 731 | name: "empty slice", 732 | args: args{ 733 | src: []uint32{}, 734 | }, 735 | want: []uint32{}, 736 | }, 737 | { 738 | name: "slice odd elements", 739 | args: args{ 740 | src: []uint32{1, 2, 3, 4, 5}, 741 | }, 742 | want: []uint32{5, 4, 3, 2, 1}, 743 | }, 744 | { 745 | name: "slice with even elements", 746 | args: args{ 747 | src: []uint32{1, 2, 3, 4}, 748 | }, 749 | want: []uint32{4, 3, 2, 1}, 750 | }, 751 | } 752 | for _, tt := range tests { 753 | t.Run(tt.name, func(t *testing.T) { 754 | if got := ReverseUint32(tt.args.src); !reflect.DeepEqual(got, tt.want) { 755 | t.Errorf("ReverseUint32() = %v, want %v", got, tt.want) 756 | } 757 | }) 758 | } 759 | } 760 | 761 | func TestReverseUint64(t *testing.T) { 762 | type args struct { 763 | src []uint64 764 | } 765 | tests := []struct { 766 | name string 767 | args args 768 | want []uint64 769 | }{ 770 | { 771 | name: "nil slice", 772 | args: args{ 773 | src: nil, 774 | }, 775 | want: nil, 776 | }, 777 | { 778 | name: "empty slice", 779 | args: args{ 780 | src: []uint64{}, 781 | }, 782 | want: []uint64{}, 783 | }, 784 | { 785 | name: "slice odd elements", 786 | args: args{ 787 | src: []uint64{1, 2, 3, 4, 5}, 788 | }, 789 | want: []uint64{5, 4, 3, 2, 1}, 790 | }, 791 | { 792 | name: "slice with even elements", 793 | args: args{ 794 | src: []uint64{1, 2, 3, 4}, 795 | }, 796 | want: []uint64{4, 3, 2, 1}, 797 | }, 798 | } 799 | for _, tt := range tests { 800 | t.Run(tt.name, func(t *testing.T) { 801 | if got := ReverseUint64(tt.args.src); !reflect.DeepEqual(got, tt.want) { 802 | t.Errorf("ReverseUint64() = %v, want %v", got, tt.want) 803 | } 804 | }) 805 | } 806 | } 807 | 808 | func TestReverseUint8(t *testing.T) { 809 | type args struct { 810 | src []uint8 811 | } 812 | tests := []struct { 813 | name string 814 | args args 815 | want []uint8 816 | }{ 817 | { 818 | name: "nil slice", 819 | args: args{ 820 | src: nil, 821 | }, 822 | want: nil, 823 | }, 824 | { 825 | name: "empty slice", 826 | args: args{ 827 | src: []uint8{}, 828 | }, 829 | want: []uint8{}, 830 | }, 831 | { 832 | name: "slice odd elements", 833 | args: args{ 834 | src: []uint8{1, 2, 3, 4, 5}, 835 | }, 836 | want: []uint8{5, 4, 3, 2, 1}, 837 | }, 838 | { 839 | name: "slice with even elements", 840 | args: args{ 841 | src: []uint8{1, 2, 3, 4}, 842 | }, 843 | want: []uint8{4, 3, 2, 1}, 844 | }, 845 | } 846 | for _, tt := range tests { 847 | t.Run(tt.name, func(t *testing.T) { 848 | if got := ReverseUint8(tt.args.src); !reflect.DeepEqual(got, tt.want) { 849 | t.Errorf("ReverseUint8() = %v, want %v", got, tt.want) 850 | } 851 | }) 852 | } 853 | } 854 | 855 | func TestReverseUintptr(t *testing.T) { 856 | type args struct { 857 | src []uintptr 858 | } 859 | tests := []struct { 860 | name string 861 | args args 862 | want []uintptr 863 | }{ 864 | { 865 | name: "nil slice", 866 | args: args{ 867 | src: nil, 868 | }, 869 | want: nil, 870 | }, 871 | { 872 | name: "empty slice", 873 | args: args{ 874 | src: []uintptr{}, 875 | }, 876 | want: []uintptr{}, 877 | }, 878 | { 879 | name: "slice odd elements", 880 | args: args{ 881 | src: []uintptr{1, 2, 3, 4, 5}, 882 | }, 883 | want: []uintptr{5, 4, 3, 2, 1}, 884 | }, 885 | { 886 | name: "slice with even elements", 887 | args: args{ 888 | src: []uintptr{1, 2, 3, 4}, 889 | }, 890 | want: []uintptr{4, 3, 2, 1}, 891 | }, 892 | } 893 | for _, tt := range tests { 894 | t.Run(tt.name, func(t *testing.T) { 895 | if got := ReverseUintptr(tt.args.src); !reflect.DeepEqual(got, tt.want) { 896 | t.Errorf("ReverseUintptr() = %v, want %v", got, tt.want) 897 | } 898 | }) 899 | } 900 | } 901 | 902 | func ExampleReverseInt() { 903 | a := []int{1, 2, 3, 4, 5} 904 | a = ReverseInt(a) 905 | fmt.Printf("%v", a) 906 | // Output: [5 4 3 2 1] 907 | } 908 | -------------------------------------------------------------------------------- /shuffle.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | // ShuffleBool shuffles (in place) a bool slice 9 | func ShuffleBool(a []bool) []bool { 10 | if len(a) <= 1 { 11 | return a 12 | } 13 | 14 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 15 | r.Shuffle(len(a), func(i, j int) { 16 | a[i], a[j] = a[j], a[i] 17 | }) 18 | 19 | return a 20 | } 21 | 22 | // ShuffleByte shuffles (in place) a byte slice 23 | func ShuffleByte(a []byte) []byte { 24 | if len(a) <= 1 { 25 | return a 26 | } 27 | 28 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 29 | r.Shuffle(len(a), func(i, j int) { 30 | a[i], a[j] = a[j], a[i] 31 | }) 32 | 33 | return a 34 | } 35 | 36 | // ShuffleComplex128 shuffles (in place) a complex128 slice 37 | func ShuffleComplex128(a []complex128) []complex128 { 38 | if len(a) <= 1 { 39 | return a 40 | } 41 | 42 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 43 | r.Shuffle(len(a), func(i, j int) { 44 | a[i], a[j] = a[j], a[i] 45 | }) 46 | 47 | return a 48 | } 49 | 50 | // ShuffleComplex64 shuffles (in place) a complex64 slice 51 | func ShuffleComplex64(a []complex64) []complex64 { 52 | if len(a) <= 1 { 53 | return a 54 | } 55 | 56 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 57 | r.Shuffle(len(a), func(i, j int) { 58 | a[i], a[j] = a[j], a[i] 59 | }) 60 | 61 | return a 62 | } 63 | 64 | // ShuffleFloat32 shuffles (in place) a float32 slice 65 | func ShuffleFloat32(a []float32) []float32 { 66 | if len(a) <= 1 { 67 | return a 68 | } 69 | 70 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 71 | r.Shuffle(len(a), func(i, j int) { 72 | a[i], a[j] = a[j], a[i] 73 | }) 74 | 75 | return a 76 | } 77 | 78 | // ShuffleFloat64 shuffles (in place) a float64 slice 79 | func ShuffleFloat64(a []float64) []float64 { 80 | if len(a) <= 1 { 81 | return a 82 | } 83 | 84 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 85 | r.Shuffle(len(a), func(i, j int) { 86 | a[i], a[j] = a[j], a[i] 87 | }) 88 | 89 | return a 90 | } 91 | 92 | // ShuffleInt shuffles (in place) a int slice 93 | func ShuffleInt(a []int) []int { 94 | if len(a) <= 1 { 95 | return a 96 | } 97 | 98 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 99 | r.Shuffle(len(a), func(i, j int) { 100 | a[i], a[j] = a[j], a[i] 101 | }) 102 | 103 | return a 104 | } 105 | 106 | // ShuffleInt16 shuffles (in place) a int16 slice 107 | func ShuffleInt16(a []int16) []int16 { 108 | if len(a) <= 1 { 109 | return a 110 | } 111 | 112 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 113 | r.Shuffle(len(a), func(i, j int) { 114 | a[i], a[j] = a[j], a[i] 115 | }) 116 | 117 | return a 118 | } 119 | 120 | // ShuffleInt32 shuffles (in place) a int32 slice 121 | func ShuffleInt32(a []int32) []int32 { 122 | if len(a) <= 1 { 123 | return a 124 | } 125 | 126 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 127 | r.Shuffle(len(a), func(i, j int) { 128 | a[i], a[j] = a[j], a[i] 129 | }) 130 | 131 | return a 132 | } 133 | 134 | // ShuffleInt64 shuffles (in place) a int64 slice 135 | func ShuffleInt64(a []int64) []int64 { 136 | if len(a) <= 1 { 137 | return a 138 | } 139 | 140 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 141 | r.Shuffle(len(a), func(i, j int) { 142 | a[i], a[j] = a[j], a[i] 143 | }) 144 | 145 | return a 146 | } 147 | 148 | // ShuffleInt8 shuffles (in place) a int8 slice 149 | func ShuffleInt8(a []int8) []int8 { 150 | if len(a) <= 1 { 151 | return a 152 | } 153 | 154 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 155 | r.Shuffle(len(a), func(i, j int) { 156 | a[i], a[j] = a[j], a[i] 157 | }) 158 | 159 | return a 160 | } 161 | 162 | // ShuffleRune shuffles (in place) a rune slice 163 | func ShuffleRune(a []rune) []rune { 164 | if len(a) <= 1 { 165 | return a 166 | } 167 | 168 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 169 | r.Shuffle(len(a), func(i, j int) { 170 | a[i], a[j] = a[j], a[i] 171 | }) 172 | 173 | return a 174 | } 175 | 176 | // ShuffleString shuffles (in place) a string slice 177 | func ShuffleString(a []string) []string { 178 | if len(a) <= 1 { 179 | return a 180 | } 181 | 182 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 183 | r.Shuffle(len(a), func(i, j int) { 184 | a[i], a[j] = a[j], a[i] 185 | }) 186 | 187 | return a 188 | } 189 | 190 | // ShuffleUint shuffles (in place) a uint slice 191 | func ShuffleUint(a []uint) []uint { 192 | if len(a) <= 1 { 193 | return a 194 | } 195 | 196 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 197 | r.Shuffle(len(a), func(i, j int) { 198 | a[i], a[j] = a[j], a[i] 199 | }) 200 | 201 | return a 202 | } 203 | 204 | // ShuffleUint16 shuffles (in place) a uint16 slice 205 | func ShuffleUint16(a []uint16) []uint16 { 206 | if len(a) <= 1 { 207 | return a 208 | } 209 | 210 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 211 | r.Shuffle(len(a), func(i, j int) { 212 | a[i], a[j] = a[j], a[i] 213 | }) 214 | 215 | return a 216 | } 217 | 218 | // ShuffleUint32 shuffles (in place) a uint32 slice 219 | func ShuffleUint32(a []uint32) []uint32 { 220 | if len(a) <= 1 { 221 | return a 222 | } 223 | 224 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 225 | r.Shuffle(len(a), func(i, j int) { 226 | a[i], a[j] = a[j], a[i] 227 | }) 228 | 229 | return a 230 | } 231 | 232 | // ShuffleUint64 shuffles (in place) a uint64 slice 233 | func ShuffleUint64(a []uint64) []uint64 { 234 | if len(a) <= 1 { 235 | return a 236 | } 237 | 238 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 239 | r.Shuffle(len(a), func(i, j int) { 240 | a[i], a[j] = a[j], a[i] 241 | }) 242 | 243 | return a 244 | } 245 | 246 | // ShuffleUint8 shuffles (in place) a uint8 slice 247 | func ShuffleUint8(a []uint8) []uint8 { 248 | if len(a) <= 1 { 249 | return a 250 | } 251 | 252 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 253 | r.Shuffle(len(a), func(i, j int) { 254 | a[i], a[j] = a[j], a[i] 255 | }) 256 | 257 | return a 258 | } 259 | 260 | // ShuffleUintptr shuffles (in place) a uintptr slice 261 | func ShuffleUintptr(a []uintptr) []uintptr { 262 | if len(a) <= 1 { 263 | return a 264 | } 265 | 266 | r := rand.New(rand.NewSource(time.Now().UnixNano())) 267 | r.Shuffle(len(a), func(i, j int) { 268 | a[i], a[j] = a[j], a[i] 269 | }) 270 | 271 | return a 272 | } 273 | -------------------------------------------------------------------------------- /sum.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import "errors" 4 | 5 | // SumByte returns the sum of the values of a byte Slice or an error in case of a nil or empty slice 6 | func SumByte(a []byte) (byte, error) { 7 | var sum byte 8 | if len(a) == 0 { 9 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 10 | } 11 | 12 | for k := range a { 13 | sum += a[k] 14 | } 15 | 16 | return sum, nil 17 | } 18 | 19 | // SumComplex128 returns the sum of the values of a complex128 Slice or an error in case of a nil or empty slice 20 | func SumComplex128(a []complex128) (complex128, error) { 21 | var sum complex128 22 | if len(a) == 0 { 23 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 24 | } 25 | 26 | for k := range a { 27 | sum += a[k] 28 | } 29 | 30 | return sum, nil 31 | } 32 | 33 | // SumComplex64 returns the sum of the values of a complex64 Slice or an error in case of a nil or empty slice 34 | func SumComplex64(a []complex64) (complex64, error) { 35 | var sum complex64 36 | if len(a) == 0 { 37 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 38 | } 39 | 40 | for k := range a { 41 | sum += a[k] 42 | } 43 | 44 | return sum, nil 45 | } 46 | 47 | // SumFloat32 returns the sum of the values of a float32 Slice or an error in case of a nil or empty slice 48 | func SumFloat32(a []float32) (float32, error) { 49 | var sum float32 50 | if len(a) == 0 { 51 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 52 | } 53 | 54 | for k := range a { 55 | sum += a[k] 56 | } 57 | 58 | return sum, nil 59 | } 60 | 61 | // SumFloat64 returns the sum of the values of a float64 Slice or an error in case of a nil or empty slice 62 | func SumFloat64(a []float64) (float64, error) { 63 | var sum float64 64 | if len(a) == 0 { 65 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 66 | } 67 | 68 | for k := range a { 69 | sum += a[k] 70 | } 71 | 72 | return sum, nil 73 | } 74 | 75 | // SumInt returns the sum of the values of a int Slice or an error in case of a nil or empty slice 76 | func SumInt(a []int) (int, error) { 77 | var sum int 78 | if len(a) == 0 { 79 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 80 | } 81 | 82 | for k := range a { 83 | sum += a[k] 84 | } 85 | 86 | return sum, nil 87 | } 88 | 89 | // SumInt16 returns the sum of the values of a int16 Slice or an error in case of a nil or empty slice 90 | func SumInt16(a []int16) (int16, error) { 91 | var sum int16 92 | if len(a) == 0 { 93 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 94 | } 95 | 96 | for k := range a { 97 | sum += a[k] 98 | } 99 | 100 | return sum, nil 101 | } 102 | 103 | // SumInt32 returns the sum of the values of a int32 Slice or an error in case of a nil or empty slice 104 | func SumInt32(a []int32) (int32, error) { 105 | var sum int32 106 | if len(a) == 0 { 107 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 108 | } 109 | 110 | for k := range a { 111 | sum += a[k] 112 | } 113 | 114 | return sum, nil 115 | } 116 | 117 | // SumInt64 returns the sum of the values of a int64 Slice or an error in case of a nil or empty slice 118 | func SumInt64(a []int64) (int64, error) { 119 | var sum int64 120 | if len(a) == 0 { 121 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 122 | } 123 | 124 | for k := range a { 125 | sum += a[k] 126 | } 127 | 128 | return sum, nil 129 | } 130 | 131 | // SumInt8 returns the sum of the values of a int8 Slice or an error in case of a nil or empty slice 132 | func SumInt8(a []int8) (int8, error) { 133 | var sum int8 134 | if len(a) == 0 { 135 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 136 | } 137 | 138 | for k := range a { 139 | sum += a[k] 140 | } 141 | 142 | return sum, nil 143 | } 144 | 145 | // SumRune returns the sum of the values of a rune Slice or an error in case of a nil or empty slice 146 | func SumRune(a []rune) (rune, error) { 147 | var sum rune 148 | if len(a) == 0 { 149 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 150 | } 151 | 152 | for k := range a { 153 | sum += a[k] 154 | } 155 | 156 | return sum, nil 157 | } 158 | 159 | // SumUint returns the sum of the values of a uint Slice or an error in case of a nil or empty slice 160 | func SumUint(a []uint) (uint, error) { 161 | var sum uint 162 | if len(a) == 0 { 163 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 164 | } 165 | 166 | for k := range a { 167 | sum += a[k] 168 | } 169 | 170 | return sum, nil 171 | } 172 | 173 | // SumUint16 returns the sum of the values of a uint16 Slice or an error in case of a nil or empty slice 174 | func SumUint16(a []uint16) (uint16, error) { 175 | var sum uint16 176 | if len(a) == 0 { 177 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 178 | } 179 | 180 | for k := range a { 181 | sum += a[k] 182 | } 183 | 184 | return sum, nil 185 | } 186 | 187 | // SumUint32 returns the sum of the values of a uint32 Slice or an error in case of a nil or empty slice 188 | func SumUint32(a []uint32) (uint32, error) { 189 | var sum uint32 190 | if len(a) == 0 { 191 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 192 | } 193 | 194 | for k := range a { 195 | sum += a[k] 196 | } 197 | 198 | return sum, nil 199 | } 200 | 201 | // SumUint64 returns the sum of the values of a uint64 Slice or an error in case of a nil or empty slice 202 | func SumUint64(a []uint64) (uint64, error) { 203 | var sum uint64 204 | if len(a) == 0 { 205 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 206 | } 207 | 208 | for k := range a { 209 | sum += a[k] 210 | } 211 | 212 | return sum, nil 213 | } 214 | 215 | // SumUint8 returns the sum of the values of a uint8 Slice or an error in case of a nil or empty slice 216 | func SumUint8(a []uint8) (uint8, error) { 217 | var sum uint8 218 | if len(a) == 0 { 219 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 220 | } 221 | 222 | for k := range a { 223 | sum += a[k] 224 | } 225 | 226 | return sum, nil 227 | } 228 | 229 | // SumUintptr returns the sum of the values of a uintptr Slice or an error in case of a nil or empty slice 230 | func SumUintptr(a []uintptr) (uintptr, error) { 231 | var sum uintptr 232 | if len(a) == 0 { 233 | return sum, errors.New("Cannot calculate the sum of a nil or empty slice") 234 | } 235 | 236 | for k := range a { 237 | sum += a[k] 238 | } 239 | 240 | return sum, nil 241 | } 242 | -------------------------------------------------------------------------------- /sum_test.go: -------------------------------------------------------------------------------- 1 | package slice 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestSumByte(t *testing.T) { 10 | type args struct { 11 | a []byte 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want byte 17 | wantErr bool 18 | }{ 19 | { 20 | name: "nil slice", 21 | args: args{ 22 | a: nil, 23 | }, 24 | want: 0, 25 | wantErr: true, 26 | }, 27 | { 28 | name: "empty slice", 29 | args: args{ 30 | a: []byte{}, 31 | }, 32 | want: 0, 33 | wantErr: true, 34 | }, 35 | { 36 | name: "non empty slice", 37 | args: args{ 38 | a: []byte{1, 2, 3}, 39 | }, 40 | want: 6, 41 | wantErr: false, 42 | }, 43 | } 44 | for _, tt := range tests { 45 | t.Run(tt.name, func(t *testing.T) { 46 | got, err := SumByte(tt.args.a) 47 | if (err != nil) != tt.wantErr { 48 | t.Errorf("SumByte() error = %v, wantErr %v", err, tt.wantErr) 49 | return 50 | } 51 | if !reflect.DeepEqual(got, tt.want) { 52 | t.Errorf("SumByte() = %v, want %v", got, tt.want) 53 | } 54 | }) 55 | } 56 | } 57 | 58 | func TestSumComplex128(t *testing.T) { 59 | type args struct { 60 | a []complex128 61 | } 62 | tests := []struct { 63 | name string 64 | args args 65 | want complex128 66 | wantErr bool 67 | }{ 68 | { 69 | name: "nil slice", 70 | args: args{ 71 | a: nil, 72 | }, 73 | want: complex(0, 0), 74 | wantErr: true, 75 | }, 76 | { 77 | name: "empty slice", 78 | args: args{ 79 | a: []complex128{}, 80 | }, 81 | want: complex(0, 0), 82 | wantErr: true, 83 | }, 84 | { 85 | name: "non empty slice", 86 | args: args{ 87 | a: []complex128{complex(1, 1), complex(2, 2), complex(3, 3)}, 88 | }, 89 | want: complex(6, 6), 90 | wantErr: false, 91 | }, 92 | } 93 | for _, tt := range tests { 94 | t.Run(tt.name, func(t *testing.T) { 95 | got, err := SumComplex128(tt.args.a) 96 | if (err != nil) != tt.wantErr { 97 | t.Errorf("SumComplex128() error = %v, wantErr %v", err, tt.wantErr) 98 | return 99 | } 100 | if !reflect.DeepEqual(got, tt.want) { 101 | t.Errorf("SumComplex128() = %v, want %v", got, tt.want) 102 | } 103 | }) 104 | } 105 | } 106 | 107 | func TestSumComplex64(t *testing.T) { 108 | type args struct { 109 | a []complex64 110 | } 111 | tests := []struct { 112 | name string 113 | args args 114 | want complex64 115 | wantErr bool 116 | }{ 117 | { 118 | name: "nil slice", 119 | args: args{ 120 | a: nil, 121 | }, 122 | want: complex(0, 0), 123 | wantErr: true, 124 | }, 125 | { 126 | name: "empty slice", 127 | args: args{ 128 | a: []complex64{}, 129 | }, 130 | want: complex(0, 0), 131 | wantErr: true, 132 | }, 133 | { 134 | name: "non empty slice", 135 | args: args{ 136 | a: []complex64{complex(1, 1), complex(2, 2), complex(3, 3)}, 137 | }, 138 | want: complex(6, 6), 139 | wantErr: false, 140 | }, 141 | } 142 | for _, tt := range tests { 143 | t.Run(tt.name, func(t *testing.T) { 144 | got, err := SumComplex64(tt.args.a) 145 | if (err != nil) != tt.wantErr { 146 | t.Errorf("SumComplex64() error = %v, wantErr %v", err, tt.wantErr) 147 | return 148 | } 149 | if !reflect.DeepEqual(got, tt.want) { 150 | t.Errorf("SumComplex64() = %v, want %v", got, tt.want) 151 | } 152 | }) 153 | } 154 | } 155 | 156 | func TestSumFloat32(t *testing.T) { 157 | type args struct { 158 | a []float32 159 | } 160 | tests := []struct { 161 | name string 162 | args args 163 | want float32 164 | wantErr bool 165 | }{ 166 | { 167 | name: "nil slice", 168 | args: args{ 169 | a: nil, 170 | }, 171 | want: 0, 172 | wantErr: true, 173 | }, 174 | { 175 | name: "empty slice", 176 | args: args{ 177 | a: []float32{}, 178 | }, 179 | want: 0, 180 | wantErr: true, 181 | }, 182 | { 183 | name: "non empty slice", 184 | args: args{ 185 | a: []float32{1.0, 2.0, 3.0}, 186 | }, 187 | want: 6.0, 188 | wantErr: false, 189 | }, 190 | } 191 | for _, tt := range tests { 192 | t.Run(tt.name, func(t *testing.T) { 193 | got, err := SumFloat32(tt.args.a) 194 | if (err != nil) != tt.wantErr { 195 | t.Errorf("SumFloat32() error = %v, wantErr %v", err, tt.wantErr) 196 | return 197 | } 198 | if !reflect.DeepEqual(got, tt.want) { 199 | t.Errorf("SumFloat32() = %v, want %v", got, tt.want) 200 | } 201 | }) 202 | } 203 | } 204 | 205 | func TestSumFloat64(t *testing.T) { 206 | type args struct { 207 | a []float64 208 | } 209 | tests := []struct { 210 | name string 211 | args args 212 | want float64 213 | wantErr bool 214 | }{ 215 | { 216 | name: "nil slice", 217 | args: args{ 218 | a: nil, 219 | }, 220 | want: 0, 221 | wantErr: true, 222 | }, 223 | { 224 | name: "empty slice", 225 | args: args{ 226 | a: []float64{}, 227 | }, 228 | want: 0, 229 | wantErr: true, 230 | }, 231 | { 232 | name: "non empty slice", 233 | args: args{ 234 | a: []float64{1.0, 2.0, 3.0}, 235 | }, 236 | want: 6.0, 237 | wantErr: false, 238 | }, 239 | } 240 | for _, tt := range tests { 241 | t.Run(tt.name, func(t *testing.T) { 242 | got, err := SumFloat64(tt.args.a) 243 | if (err != nil) != tt.wantErr { 244 | t.Errorf("SumFloat64() error = %v, wantErr %v", err, tt.wantErr) 245 | return 246 | } 247 | if !reflect.DeepEqual(got, tt.want) { 248 | t.Errorf("SumFloat64() = %v, want %v", got, tt.want) 249 | } 250 | }) 251 | } 252 | } 253 | 254 | func TestSumInt(t *testing.T) { 255 | type args struct { 256 | a []int 257 | } 258 | tests := []struct { 259 | name string 260 | args args 261 | want int 262 | wantErr bool 263 | }{ 264 | { 265 | name: "nil slice", 266 | args: args{ 267 | a: nil, 268 | }, 269 | want: 0, 270 | wantErr: true, 271 | }, 272 | { 273 | name: "empty slice", 274 | args: args{ 275 | a: []int{}, 276 | }, 277 | want: 0, 278 | wantErr: true, 279 | }, 280 | { 281 | name: "non empty slice", 282 | args: args{ 283 | a: []int{1, 2, 3}, 284 | }, 285 | want: 6, 286 | wantErr: false, 287 | }, 288 | } 289 | for _, tt := range tests { 290 | t.Run(tt.name, func(t *testing.T) { 291 | got, err := SumInt(tt.args.a) 292 | if (err != nil) != tt.wantErr { 293 | t.Errorf("SumInt() error = %v, wantErr %v", err, tt.wantErr) 294 | return 295 | } 296 | if !reflect.DeepEqual(got, tt.want) { 297 | t.Errorf("SumInt() = %v, want %v", got, tt.want) 298 | } 299 | }) 300 | } 301 | } 302 | 303 | func TestSumInt16(t *testing.T) { 304 | type args struct { 305 | a []int16 306 | } 307 | tests := []struct { 308 | name string 309 | args args 310 | want int16 311 | wantErr bool 312 | }{ 313 | { 314 | name: "nil slice", 315 | args: args{ 316 | a: nil, 317 | }, 318 | want: 0, 319 | wantErr: true, 320 | }, 321 | { 322 | name: "empty slice", 323 | args: args{ 324 | a: []int16{}, 325 | }, 326 | want: 0, 327 | wantErr: true, 328 | }, 329 | { 330 | name: "non empty slice", 331 | args: args{ 332 | a: []int16{1, 2, 3}, 333 | }, 334 | want: 6, 335 | wantErr: false, 336 | }, 337 | } 338 | for _, tt := range tests { 339 | t.Run(tt.name, func(t *testing.T) { 340 | got, err := SumInt16(tt.args.a) 341 | if (err != nil) != tt.wantErr { 342 | t.Errorf("SumInt16() error = %v, wantErr %v", err, tt.wantErr) 343 | return 344 | } 345 | if !reflect.DeepEqual(got, tt.want) { 346 | t.Errorf("SumInt16() = %v, want %v", got, tt.want) 347 | } 348 | }) 349 | } 350 | } 351 | 352 | func TestSumInt32(t *testing.T) { 353 | type args struct { 354 | a []int32 355 | } 356 | tests := []struct { 357 | name string 358 | args args 359 | want int32 360 | wantErr bool 361 | }{ 362 | { 363 | name: "nil slice", 364 | args: args{ 365 | a: nil, 366 | }, 367 | want: 0, 368 | wantErr: true, 369 | }, 370 | { 371 | name: "empty slice", 372 | args: args{ 373 | a: []int32{}, 374 | }, 375 | want: 0, 376 | wantErr: true, 377 | }, 378 | { 379 | name: "non empty slice", 380 | args: args{ 381 | a: []int32{1, 2, 3}, 382 | }, 383 | want: 6, 384 | wantErr: false, 385 | }, 386 | } 387 | for _, tt := range tests { 388 | t.Run(tt.name, func(t *testing.T) { 389 | got, err := SumInt32(tt.args.a) 390 | if (err != nil) != tt.wantErr { 391 | t.Errorf("SumInt32() error = %v, wantErr %v", err, tt.wantErr) 392 | return 393 | } 394 | if !reflect.DeepEqual(got, tt.want) { 395 | t.Errorf("SumInt32() = %v, want %v", got, tt.want) 396 | } 397 | }) 398 | } 399 | } 400 | 401 | func TestSumInt64(t *testing.T) { 402 | type args struct { 403 | a []int64 404 | } 405 | tests := []struct { 406 | name string 407 | args args 408 | want int64 409 | wantErr bool 410 | }{ 411 | { 412 | name: "nil slice", 413 | args: args{ 414 | a: nil, 415 | }, 416 | want: 0, 417 | wantErr: true, 418 | }, 419 | { 420 | name: "empty slice", 421 | args: args{ 422 | a: []int64{}, 423 | }, 424 | want: 0, 425 | wantErr: true, 426 | }, 427 | { 428 | name: "non empty slice", 429 | args: args{ 430 | a: []int64{1, 2, 3}, 431 | }, 432 | want: 6, 433 | wantErr: false, 434 | }, 435 | } 436 | for _, tt := range tests { 437 | t.Run(tt.name, func(t *testing.T) { 438 | got, err := SumInt64(tt.args.a) 439 | if (err != nil) != tt.wantErr { 440 | t.Errorf("SumInt64() error = %v, wantErr %v", err, tt.wantErr) 441 | return 442 | } 443 | if !reflect.DeepEqual(got, tt.want) { 444 | t.Errorf("SumInt64() = %v, want %v", got, tt.want) 445 | } 446 | }) 447 | } 448 | } 449 | 450 | func TestSumInt8(t *testing.T) { 451 | type args struct { 452 | a []int8 453 | } 454 | tests := []struct { 455 | name string 456 | args args 457 | want int8 458 | wantErr bool 459 | }{ 460 | { 461 | name: "nil slice", 462 | args: args{ 463 | a: nil, 464 | }, 465 | want: 0, 466 | wantErr: true, 467 | }, 468 | { 469 | name: "empty slice", 470 | args: args{ 471 | a: []int8{}, 472 | }, 473 | want: 0, 474 | wantErr: true, 475 | }, 476 | { 477 | name: "non empty slice", 478 | args: args{ 479 | a: []int8{1, 2, 3}, 480 | }, 481 | want: 6, 482 | wantErr: false, 483 | }, 484 | } 485 | for _, tt := range tests { 486 | t.Run(tt.name, func(t *testing.T) { 487 | got, err := SumInt8(tt.args.a) 488 | if (err != nil) != tt.wantErr { 489 | t.Errorf("SumInt8() error = %v, wantErr %v", err, tt.wantErr) 490 | return 491 | } 492 | if !reflect.DeepEqual(got, tt.want) { 493 | t.Errorf("SumInt8() = %v, want %v", got, tt.want) 494 | } 495 | }) 496 | } 497 | } 498 | 499 | func TestSumRune(t *testing.T) { 500 | type args struct { 501 | a []rune 502 | } 503 | tests := []struct { 504 | name string 505 | args args 506 | want rune 507 | wantErr bool 508 | }{ 509 | { 510 | name: "nil slice", 511 | args: args{ 512 | a: nil, 513 | }, 514 | want: 0, 515 | wantErr: true, 516 | }, 517 | { 518 | name: "empty slice", 519 | args: args{ 520 | a: []rune{}, 521 | }, 522 | want: 0, 523 | wantErr: true, 524 | }, 525 | { 526 | name: "non empty slice", 527 | args: args{ 528 | a: []rune{1, 2, 3}, 529 | }, 530 | want: 6, 531 | wantErr: false, 532 | }, 533 | } 534 | for _, tt := range tests { 535 | t.Run(tt.name, func(t *testing.T) { 536 | got, err := SumRune(tt.args.a) 537 | if (err != nil) != tt.wantErr { 538 | t.Errorf("SumRune() error = %v, wantErr %v", err, tt.wantErr) 539 | return 540 | } 541 | if !reflect.DeepEqual(got, tt.want) { 542 | t.Errorf("SumRune() = %v, want %v", got, tt.want) 543 | } 544 | }) 545 | } 546 | } 547 | 548 | func TestSumUint(t *testing.T) { 549 | type args struct { 550 | a []uint 551 | } 552 | tests := []struct { 553 | name string 554 | args args 555 | want uint 556 | wantErr bool 557 | }{ 558 | { 559 | name: "nil slice", 560 | args: args{ 561 | a: nil, 562 | }, 563 | want: 0, 564 | wantErr: true, 565 | }, 566 | { 567 | name: "empty slice", 568 | args: args{ 569 | a: []uint{}, 570 | }, 571 | want: 0, 572 | wantErr: true, 573 | }, 574 | { 575 | name: "non empty slice", 576 | args: args{ 577 | a: []uint{1, 2, 3}, 578 | }, 579 | want: 6, 580 | wantErr: false, 581 | }, 582 | } 583 | for _, tt := range tests { 584 | t.Run(tt.name, func(t *testing.T) { 585 | got, err := SumUint(tt.args.a) 586 | if (err != nil) != tt.wantErr { 587 | t.Errorf("SumUint() error = %v, wantErr %v", err, tt.wantErr) 588 | return 589 | } 590 | if !reflect.DeepEqual(got, tt.want) { 591 | t.Errorf("SumUint() = %v, want %v", got, tt.want) 592 | } 593 | }) 594 | } 595 | } 596 | 597 | func TestSumUint16(t *testing.T) { 598 | type args struct { 599 | a []uint16 600 | } 601 | tests := []struct { 602 | name string 603 | args args 604 | want uint16 605 | wantErr bool 606 | }{ 607 | { 608 | name: "nil slice", 609 | args: args{ 610 | a: nil, 611 | }, 612 | want: 0, 613 | wantErr: true, 614 | }, 615 | { 616 | name: "empty slice", 617 | args: args{ 618 | a: []uint16{}, 619 | }, 620 | want: 0, 621 | wantErr: true, 622 | }, 623 | { 624 | name: "non empty slice", 625 | args: args{ 626 | a: []uint16{1, 2, 3}, 627 | }, 628 | want: 6, 629 | wantErr: false, 630 | }, 631 | } 632 | for _, tt := range tests { 633 | t.Run(tt.name, func(t *testing.T) { 634 | got, err := SumUint16(tt.args.a) 635 | if (err != nil) != tt.wantErr { 636 | t.Errorf("SumUint16() error = %v, wantErr %v", err, tt.wantErr) 637 | return 638 | } 639 | if !reflect.DeepEqual(got, tt.want) { 640 | t.Errorf("SumUint16() = %v, want %v", got, tt.want) 641 | } 642 | }) 643 | } 644 | } 645 | 646 | func TestSumUint32(t *testing.T) { 647 | type args struct { 648 | a []uint32 649 | } 650 | tests := []struct { 651 | name string 652 | args args 653 | want uint32 654 | wantErr bool 655 | }{ 656 | { 657 | name: "nil slice", 658 | args: args{ 659 | a: nil, 660 | }, 661 | want: 0, 662 | wantErr: true, 663 | }, 664 | { 665 | name: "empty slice", 666 | args: args{ 667 | a: []uint32{}, 668 | }, 669 | want: 0, 670 | wantErr: true, 671 | }, 672 | { 673 | name: "non empty slice", 674 | args: args{ 675 | a: []uint32{1, 2, 3}, 676 | }, 677 | want: 6, 678 | wantErr: false, 679 | }, 680 | } 681 | for _, tt := range tests { 682 | t.Run(tt.name, func(t *testing.T) { 683 | got, err := SumUint32(tt.args.a) 684 | if (err != nil) != tt.wantErr { 685 | t.Errorf("SumUint32() error = %v, wantErr %v", err, tt.wantErr) 686 | return 687 | } 688 | if !reflect.DeepEqual(got, tt.want) { 689 | t.Errorf("SumUint32() = %v, want %v", got, tt.want) 690 | } 691 | }) 692 | } 693 | } 694 | 695 | func TestSumUint64(t *testing.T) { 696 | type args struct { 697 | a []uint64 698 | } 699 | tests := []struct { 700 | name string 701 | args args 702 | want uint64 703 | wantErr bool 704 | }{ 705 | { 706 | name: "nil slice", 707 | args: args{ 708 | a: nil, 709 | }, 710 | want: 0, 711 | wantErr: true, 712 | }, 713 | { 714 | name: "empty slice", 715 | args: args{ 716 | a: []uint64{}, 717 | }, 718 | want: 0, 719 | wantErr: true, 720 | }, 721 | { 722 | name: "non empty slice", 723 | args: args{ 724 | a: []uint64{1, 2, 3}, 725 | }, 726 | want: 6, 727 | wantErr: false, 728 | }, 729 | } 730 | for _, tt := range tests { 731 | t.Run(tt.name, func(t *testing.T) { 732 | got, err := SumUint64(tt.args.a) 733 | if (err != nil) != tt.wantErr { 734 | t.Errorf("SumUint64() error = %v, wantErr %v", err, tt.wantErr) 735 | return 736 | } 737 | if !reflect.DeepEqual(got, tt.want) { 738 | t.Errorf("SumUint64() = %v, want %v", got, tt.want) 739 | } 740 | }) 741 | } 742 | } 743 | 744 | func TestSumUint8(t *testing.T) { 745 | type args struct { 746 | a []uint8 747 | } 748 | tests := []struct { 749 | name string 750 | args args 751 | want uint8 752 | wantErr bool 753 | }{ 754 | { 755 | name: "nil slice", 756 | args: args{ 757 | a: nil, 758 | }, 759 | want: 0, 760 | wantErr: true, 761 | }, 762 | { 763 | name: "empty slice", 764 | args: args{ 765 | a: []uint8{}, 766 | }, 767 | want: 0, 768 | wantErr: true, 769 | }, 770 | { 771 | name: "non empty slice", 772 | args: args{ 773 | a: []uint8{1, 2, 3}, 774 | }, 775 | want: 6, 776 | wantErr: false, 777 | }, 778 | } 779 | for _, tt := range tests { 780 | t.Run(tt.name, func(t *testing.T) { 781 | got, err := SumUint8(tt.args.a) 782 | if (err != nil) != tt.wantErr { 783 | t.Errorf("SumUint8() error = %v, wantErr %v", err, tt.wantErr) 784 | return 785 | } 786 | if !reflect.DeepEqual(got, tt.want) { 787 | t.Errorf("SumUint8() = %v, want %v", got, tt.want) 788 | } 789 | }) 790 | } 791 | } 792 | 793 | func TestSumUintptr(t *testing.T) { 794 | type args struct { 795 | a []uintptr 796 | } 797 | tests := []struct { 798 | name string 799 | args args 800 | want uintptr 801 | wantErr bool 802 | }{ 803 | { 804 | name: "nil slice", 805 | args: args{ 806 | a: nil, 807 | }, 808 | want: 0, 809 | wantErr: true, 810 | }, 811 | { 812 | name: "empty slice", 813 | args: args{ 814 | a: []uintptr{}, 815 | }, 816 | want: 0, 817 | wantErr: true, 818 | }, 819 | { 820 | name: "non empty slice", 821 | args: args{ 822 | a: []uintptr{1, 2, 3}, 823 | }, 824 | want: 6, 825 | wantErr: false, 826 | }, 827 | } 828 | for _, tt := range tests { 829 | t.Run(tt.name, func(t *testing.T) { 830 | got, err := SumUintptr(tt.args.a) 831 | if (err != nil) != tt.wantErr { 832 | t.Errorf("SumUintptr() error = %v, wantErr %v", err, tt.wantErr) 833 | return 834 | } 835 | if !reflect.DeepEqual(got, tt.want) { 836 | t.Errorf("SumUintptr() = %v, want %v", got, tt.want) 837 | } 838 | }) 839 | } 840 | } 841 | 842 | func ExampleSumInt() { 843 | a := []int{1, 2, 3} 844 | sum, err := SumInt(a) 845 | fmt.Printf("%d, %v", sum, err) 846 | // Output: 6, 847 | } 848 | --------------------------------------------------------------------------------