Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a new functions - Remove #172

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 48 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
focuses on type safety, performance and immutability.

- [Quick Start](#quick-start)
* [Install/Update](#install-update)
* [Built-in Types](#built-in-types)
* [Custom Types](#custom-types)
* [Custom Equality](#custom-equality)
* [Custom Stringer](#custom-stringer)
* [Limiting Functions Generated](#limiting-functions-generated)
* [Install/Update](#install-update)
* [Built-in Types](#built-in-types)
* [Custom Types](#custom-types)
* [Custom Equality](#custom-equality)
* [Custom Stringer](#custom-stringer)
* [Limiting Functions Generated](#limiting-functions-generated)
- [Functions](#functions)
- [FAQ](#faq)
* [What are the requirements?](#what-are-the-requirements-)
* [What are the goals of `pie`?](#what-are-the-goals-of--pie--)
* [How do I contribute a function?](#how-do-i-contribute-a-function-)
* [Why is the emoji a slice of pizza instead of a pie?](#why-is-the-emoji-a-slice-of-pizza-instead-of-a-pie-)
* [How do I exclude generated files from code coverage?](#how-do-i-exclude-generated-files-from-code-coverage-)
* [What are the requirements?](#what-are-the-requirements-)
* [What are the goals of `pie`?](#what-are-the-goals-of--pie--)
* [How do I contribute a function?](#how-do-i-contribute-a-function-)
* [Why is the emoji a slice of pizza instead of a pie?](#why-is-the-emoji-a-slice-of-pizza-instead-of-a-pie-)
* [How do I exclude generated files from code coverage?](#how-do-i-exclude-generated-files-from-code-coverage-)

# Quick Start

Expand Down Expand Up @@ -167,10 +167,10 @@ Below is a summary of the available functions.
The letters in brackets indicate:

- **E**: The function will use the `Equals` method if it is available. See
*Custom Equality*.
*Custom Equality*.

- **S**: The function will use the `String` method if it is available. See
*Custom Stringer*.
*Custom Stringer*.

| Function | String | Number | Struct | Maps | Big-O | Description |
| --------------------------------------- | :----: | :----: | :----: | :--: | :------: | ----------- |
Expand Down Expand Up @@ -216,6 +216,7 @@ The letters in brackets indicate:
| [`Product`](#product) | | ✓ | | | n | Product is the product of all of the elements. |
| [`Random`](#random) | ✓ | ✓ | ✓ | | 1 | Random returns a random element by your rand.Source, or zero |
| [`Reduce`](#reduce) | ✓ | ✓ | | | n | Reduce continually applies the provided function over the slice. Reducing the elements to a single value. |
| [`Remove`](#remove) | ✓ | ✓ | | ✓ | n | Remove returns a new slice that does not include any of the items. |
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maps should not be ticked.

Did you format this file after running generate.go?

| [`Reverse`](#reverse) | ✓ | ✓ | ✓ | | n | Reverse returns a new copy of the slice with the elements ordered in reverse. This is useful when combined with Sort to get a descending sort order: |
| [`Send`](#send) | ✓ | ✓ | ✓ | | n | Send sends elements to channel in normal act it sends all elements but if func canceled it can be less |
| [`Sequence`](#sequence) | | ✓ | | | n | Sequence generates all numbers in range or returns nil if params invalid |
Expand Down Expand Up @@ -586,6 +587,20 @@ Returns a zero value of ElementType if there are no elements in the slice. It wi
Otherwise returns result of applying reducer from left to right.


## Remove

Remove returns a new slice that does not include any of the items.

Usage Example:

```go
listA := pie.Strings{"1", "2"}
listB := pie.Strings{"1", "3"}

// [ "2" ]
fmt.Println(listA.Remove(listB...))
```

## Reverse

Reverse returns a new copy of the slice with the elements ordered in reverse.
Expand Down Expand Up @@ -616,9 +631,9 @@ Sequence generates all numbers in range or returns nil if params invalid


There are 3 variations to generate:
1. [0, n).
2. [min, max).
3. [min, max) with step.
1. [0, n).
2. [min, max).
3. [min, max) with step.


if len(params) == 1 considered that will be returned slice between 0 and n,
Expand All @@ -636,9 +651,9 @@ SequenceUsing generates slice in range using creator function


There are 3 variations to generate:
1. [0, n).
2. [min, max).
3. [min, max) with step.
1. [0, n).
2. [min, max).
3. [min, max) with step.


if len(params) == 1 considered that will be returned slice between 0 and n,
Expand Down Expand Up @@ -771,16 +786,16 @@ Due to Go's randomization of iterating maps the order is not deterministic.
## What are the goals of `pie`?

1. **Type safety.** I never want to hit runtime bugs because I could pass in the
wrong type, or perform an invalid type case out the other end.
wrong type, or perform an invalid type case out the other end.

2. **Performance.** The functions need to be as fast as native Go
implementations otherwise there's no point in this library existing.
implementations otherwise there's no point in this library existing.

3. **Nil-safe.** All of the functions will happily accept nil and treat them as
empty slices. Apart from less possible panics, it makes it easier to chain.
empty slices. Apart from less possible panics, it makes it easier to chain.

4. **Immutable.** Functions never modify inputs, unlike some built-ins such as
`sort.Strings`.
`sort.Strings`.

## How do I contribute a function?

Expand All @@ -789,26 +804,26 @@ Pull requests are always welcome.
Here is a comprehensive list of steps to follow to add a new function:

1. Create a new file in the `functions/` directory. The file should be named the
same as the function. You must include documentation for your function.
same as the function. You must include documentation for your function.

2. Update `functions/main.go` to register the new function by adding an entry to
`Functions`. Make sure you choose the correct `For` value that is appropriate
for your function.
`Functions`. Make sure you choose the correct `For` value that is appropriate
for your function.

3. Run `go generate ./... && go install && go generate ./...`. The first
`generate` is to create the pie templates, `install` will update your binary for
the annotations and the second `generate` will use the newly created templates
to update the generated code for the internal types. If you encounter errors
with your code you can safely rerun the command above.
`generate` is to create the pie templates, `install` will update your binary for
the annotations and the second `generate` will use the newly created templates
to update the generated code for the internal types. If you encounter errors
with your code you can safely rerun the command above.

4. If you chose `ForAll` or `ForStructs`, then you must add unit tests to
`pie/carpointers_test.go` and `pie/cars_test.go`.
`pie/carpointers_test.go` and `pie/cars_test.go`.

5. If you chose `ForAll`, `ForNumbersAndStrings` or `ForNumbers`, then you must
add unit tests to `pie/float64s_test.go` and `pie/ints_test.go`.
add unit tests to `pie/float64s_test.go` and `pie/ints_test.go`.

6. If you chose `ForAll` or `ForStrings`, then you must add unit tests to
`pie/strings_test.go`.
`pie/strings_test.go`.

7. If you chose `ForMaps`, then you must add unit tests to `pie/currencies.go`.

Expand Down
1 change: 1 addition & 0 deletions functions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ var Functions = []struct {
{"Product", "product.go", ForNumbers, "n"},
{"Random", "random.go", ForAll, "1"},
{"Reduce", "reduce.go", ForNumbersAndStrings, "n"},
{"Remove", "remove.go", ForNumbersAndStrings, "n"},
{"Reverse", "reverse.go", ForAll, "n"},
{"Send", "send.go", ForAll, "n"},
{"Sequence", "sequence.go", ForNumbers, "n"},
Expand Down
21 changes: 21 additions & 0 deletions functions/remove.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package functions

// Remove returns a new slice that does not include any of the items.
func (ss SliceType) Remove(items ...ElementType) (result SliceType) {
if len(items) == 0 {
return items
}

ss2 := make(map[ElementType]bool, len(items))
for _, item := range items {
ss2[item] = true
}

result = SliceType{}
elliotchance marked this conversation as resolved.
Show resolved Hide resolved
for _, v := range ss {
elliotchance marked this conversation as resolved.
Show resolved Hide resolved
if !ss2[v] {
result = append(result, v)
}
}
return
}
20 changes: 20 additions & 0 deletions pie/float64s_pie.go
Original file line number Diff line number Diff line change
Expand Up @@ -989,3 +989,23 @@ func (ss Float64s) Unshift(elements ...float64) (unshift Float64s) {

return
}

// Remove returns a new slice that does not include any of the items.
func (ss Float64s) Remove(items ...float64) (result Float64s) {
if len(items) == 0 {
return items
}

ss2 := make(map[float64]bool, len(items))
for _, item := range items {
ss2[item] = true
}

result = Float64s{}
for _, v := range ss {
if !ss2[v] {
result = append(result, v)
}
}
return
}
20 changes: 20 additions & 0 deletions pie/ints_pie.go
Original file line number Diff line number Diff line change
Expand Up @@ -989,3 +989,23 @@ func (ss Ints) Unshift(elements ...int) (unshift Ints) {

return
}

// Remove returns a new slice that does not include any of the items.
func (ss Ints) Remove(items ...int) (result Ints) {
if len(items) == 0 {
return items
}

ss2 := make(map[int]bool, len(items))
for _, item := range items {
ss2[item] = true
}

result = Ints{}
for _, v := range ss {
if !ss2[v] {
result = append(result, v)
}
}
return
}
20 changes: 20 additions & 0 deletions pie/strings_pie.go
Original file line number Diff line number Diff line change
Expand Up @@ -874,3 +874,23 @@ func (ss Strings) Unshift(elements ...string) (unshift Strings) {

return
}

// Remove returns a new slice that does not include any of the items.
func (ss Strings) Remove(items ...string) (result Strings) {
if len(items) == 0 {
return items
}

ss2 := make(map[string]bool, len(items))
for _, item := range items {
ss2[item] = true
}

result = Strings{}
for _, v := range ss {
if !ss2[v] {
result = append(result, v)
}
}
return
}
22 changes: 22 additions & 0 deletions template.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.