Skip to content

Commit

Permalink
Feature/generic (#30)
Browse files Browse the repository at this point in the history
Reworked package to use Golang generics.
  • Loading branch information
lindsaygelle committed Sep 13, 2023
1 parent 31a2e27 commit 743802c
Show file tree
Hide file tree
Showing 24 changed files with 641 additions and 7,456 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ jobs:
- uses: actions/setup-go@v4
- run: go install golang.org/x/lint/golint@latest
- run: golint -set_exit_status ./...
- run: go test ./...
- run: go test ./... -v
2 changes: 0 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,3 @@ repos:
rev: v2.1.0
hooks:
- id: codespell
exclude: |
(?x)^.*(\.go)$
237 changes: 106 additions & 131 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,186 +3,161 @@

Slice is a Go package that offers a versatile set of pre-built slices with extended functionality. It abstracts common list operations, such as appending, deleting, concatenating, mapping, and more, making it easier to work with slices in Go.

Gopher artwork was sourced from [egonelbre/gophers](https://github.com/egonelbre/gophers).

[![Go Reference](https://pkg.go.dev/badge/github.com/lindsaygelle/slice.svg)](https://pkg.go.dev/github.com/lindsaygelle/slice)
[![GitHub](https://img.shields.io/github/license/lindsaygelle/slice)](/LICENSE)


## Features
* Common List Operations: Slice provides a comprehensive set of list operations like appending, deleting, concatenating, mapping, reversing, and more, all seamlessly integrated into single package.
* Memory Management: Slice takes care of allocating and deallocating memory as needed, making your code cleaner and safer.
* Type-Agnostic: Slice works effortlessly with a mix of data types, making it a valuable tool for dealing with collections of data.
* Generic Go Struct Wrapping: You can easily wrap the slice.Slice type in your custom Go struct to handle type-specific operations, allowing for robust, type-safe code.
* Intuitive Constructor Functions: Each Slice interface comes with a dedicated constructor function for creating slices conveniently.
* No Underlying Slice Exposure: To prevent mixing incompatible data types, Slice interfaces do not expose the underlying slice.Slice. While recommended for custom implementations, it's not mandatory.


## Installation
Add slice as a dependency to your Go project using the following command:

Getting started with Slice is a breeze. You can install it in your Go project using `go get`:
```sh
go get -u github.com/lindsaygelle/slice
go get github.com/lindsaygelle/slice
```

## Docker
You can utilize slice within a Docker container with the provided Dockerfile. Here's how to build and run the container:
## Usage
To begin using Slice, simply import the package into your Go code:

Building the Docker container.
```sh
docker build . -t slice
```Go
import (
"github.com/lindsaygelle/slice"
)
```

Developing and running Go from within the Docker container.
```sh
docker run -it --rm --name slice slice
Creating and Initializing a Slice:
```Go
// Create an empty slice of integers
s := &slice.Slice[int]{}
```

A docker-compose file has also been added for convenience.
```sh
docker-compose up -d
Appending Elements to a Slice:
```Go
// Append values to the slice
s.Append(1, 2, 3)
```

## Usage
To create a slice for a provided data type, you can use a provided constructor function.

Getting the Length of a Slice:
```Go
// Example for string slice
s := slice.NewString("apple", "banana", "cherry")
// Get the length of the slice
length := s.Length()
```

Use the methods provided by the initialized slice interface to perform various list-like operations. Here are some common operations:

Deleting an Element from a Slice:
```Go
// Append elements to the slice
s.Append("date", "fig")

// Check if an index is within bounds
inBounds := s.Bounds(2)

// Pop the last element from the slice
poppedElement := s.Pop()
// Delete an element at index 2
s.Delete(2)
```

You can sort the slice and iterate over its elements easily:

Iterating Over a Slice:
```Go
// Example for sorting and iteration
sortedSlice := s.Sort()
sortedSlice.Each(func(index int, value string) {
fmt.Println(index, value)
// Iterate over the slice and print each element
s.Each(func(index int, value int) {
fmt.Printf("Index: %d, Value: %d\n", index, value)
})
```

That's it! You're ready to use the slice package to simplify your slice operations in Go. Explore the package documentation for a complete list of available methods and advanced usage patterns.

Reversing a Slice:
```Go
// Reverse the order of elements in the slice
s.Reverse()
```

## Slices
Slicing a Slice:
```Go
// Slice the slice from index 1 to 3
s.Slice(1, 3)
```

Each slice is designed to handle a specific Go type. You can easily create, manipulate, and check bounds on these slices through the provided methods.
Swapping Elements in a Slice:
```Go
// Swap elements at indices 1 and 2
s.Swap(1, 2)
```

More complicated examples:
```Go
package main
// Create a slice of strings
strSlice := &slice.Slice[string]{"apple", "banana", "cherry"}

import (
"fmt"
// Append multiple values to the slice
strSlice.Append("date", "elderberry")

"github.com/lindsaygelle/slice"
)
// Check if the slice contains a specific value
containsCherry := strSlice.Contains("cherry") // Should return true

var (
// []byte
b slice.Byte
// []complex64
c64 slice.Complex64
// []complex128
c128 slice.Complex128
// []float32
f32 slice.Float32
// []float64
f64 slice.Float64
// []interface{}
i slice.Int
// []int8
i8 slice.Int8
// []int16
i16 slice.Int16
// []int32
i32 slice.Int32
// []int64
i64 slice.Int64
// []rune
r slice.Rune
// []interface{}
s *slice.Slice
// []uint
u slice.UInt
// []uint8
u8 slice.UInt8
// []uint16
u16 slice.UInt16
// []uint32
u32 slice.UInt32
// []uint64
u64 slice.UInt64
)
// Replace the element at index 2 with "grape"
strSlice.Replace(2, "grape")

// Get the length of the slice
strLength := strSlice.Length()

// Iterate over the slice and print each element
strSlice.Each(func(index int, value string) {
fmt.Printf("Index %d: %s\n", index, value)
})
```

Using a complex type:
```Go
import (
"github.com/lindsaygelle/slice"
)
// Define a custom struct
type Person struct {
Name string
Age int
Email string
}

func main() {
var (
numbers = slice.NewInt(6, 1, 2, 3)
)
numbers.Sort().Each(func(i int, n int) {
fmt.Println(i, n) // (0, 1), (1, 2), (2, 3), (3, 6)
})
// Create a slice of Person structs
people := &slice.Slice[Person]{
{Name: "Alice", Age: 30, Email: "[email protected]"},
{Name: "Bob", Age: 25, Email: "[email protected]"},
}
```

## Extending
// Append a new person to the slice
newPerson := Person{Name: "Charlie", Age: 35, Email: "[email protected]"}
people.Append(newPerson)

Slice supports interface extension by wrapping the Slice in an struct and exposing a corresponding interface. This is the same pattern implemented by this package and is used for the provided interfaces.
// Find the index of a person with a specific email address
index := people.FindIndex(func(p Person) bool {
return p.Email == "[email protected]"
})

```Go
package food
// Slice the slice to include only people aged 30 or older
people.Slice(1, people.Length())

import (
"github.com/lindsaygelle/slice"
)
// Reverse the order of people in the slice
people.Reverse()

// Food is a struct that describes food.
type Food struct {
Name string
}
// Iterate over the slice and print each person's details
people.Each(func(index int, person Person) {
fmt.Printf("Index %d: Name: %s, Age: %d, Email: %s\n", index, person.Name, person.Age, person.Email)
})
```

// FoodSlice is an interface that contains a collection of Food.
type FoodSlice interface {
Append(Food) FoodSlice
Prepend(Food) FoodSlice
}
## Docker
Slice is Docker-friendly! You can easily incorporate Slice into a Docker container using the provided Dockerfile. Here are the steps to build and run the container:

// food is a struct that interfaces with slice.Slice.
type food struct { s *slice.Slice }
Building the Docker container:
```sh
docker build . -t slice
```

// Append adds Food structs to the tail of the FoodSlice.
func (f *food) Append(food ...Food) FoodSlice {
f.s.Append(food...)
return f
}
Developing and running Go within the Docker container:
```sh
docker run -it --rm --name slice slice
```

// Prepend adds Food structs to the head of the FoodSlice.
func (f *food) Prepend(food ...Food) FoodSlice {
f.s.Prepend(food...)
return f
}
A docker-compose file has also been included for convenience:
```sh
docker-compose up -d
```

## Contributing
Contributions to Slice are welcome! If you have any ideas, bug reports, or enhancements, please submit them as GitHub issues or create a pull request with your changes. For major contributions, it is recommended to discuss your ideas first by creating an issue to ensure alignment with the project's goals and direction. Please see the [CONTRIBUTION](./CONTRIBUTING.md) file fore more details.
We warmly welcome contributions to Slice. Whether you have innovative ideas, bug reports, or enhancements in mind, please share them with us by submitting GitHub issues or creating pull requests. For substantial contributions, it's a good practice to start a discussion by creating an issue to ensure alignment with the project's goals and direction. Refer to the [CONTRIBUTING](./CONTRIBUTING.md) file for comprehensive details.

## Branching
For a smooth collaboration experience, we have established branch naming conventions and guidelines. Please consult the [BRANCH_NAMING_CONVENTION](./BRANCH_NAMING_CONVENTION.md) document for comprehensive information and best practices.

## License
Slice is licensed under the MIT License. Feel free to use, modify, and distribute the code within this repository as per the terms of the license. Please see the [LICENSE](./LICENSE) file for more details.
Slice is released under the MIT License, granting you the freedom to use, modify, and distribute the code within this repository in accordance with the terms of the license. For additional information, please review the [LICENSE](./LICENSE) file.

## Acknowledgements
We express our gratitude to [egonelbre/gophers](https://github.com/egonelbre/gophers) for providing the delightful Gopher artwork used in our social preview. Don't hesitate to pay them a visit!
Loading

0 comments on commit 743802c

Please sign in to comment.