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

Renames #89

Merged
merged 5 commits into from
May 5, 2019
Merged
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
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ import (

func main() {
name := pie.Strings{"Bob", "Sally", "John", "Jane"}.
Unselect(func (name string) bool {
FilterNot(func (name string) bool {
return strings.HasPrefix(name, "J")
}).
Transform(strings.ToUpper).
Map(strings.ToUpper).
Last()

fmt.Println(name) // "SALLY"
Expand Down Expand Up @@ -85,7 +85,7 @@ cars := Cars{
{"Jane", "red"},
}

redCars := cars.Select(func(car Car) bool {
redCars := cars.Filter(func(car Car) bool {
return car.Color == "red"
})

Expand All @@ -95,10 +95,10 @@ redCars := cars.Select(func(car Car) bool {
Or, more complex operations can be chained:

```go
cars.Unselect(func (car Car) {
cars.FilterNot(func (car Car) {
return strings.HasPrefix(car.Name, "J")
}).
Transform(func (car Car) Car {
Map(func (car Car) Car {
car.Name = strings.ToUpper(car.Name)

return car
Expand All @@ -115,10 +115,10 @@ creates a lot of unused code. You can limit the functions generated by chaining
the function names with a dot syntax, like:

```go
//go:generate myInts.Average.Sum myStrings.Select
//go:generate myInts.Average.Sum myStrings.Filter
```

This will only generate `myInts.Average`, `myInts.Sum` and `myStrings.Select`.
This will only generate `myInts.Average`, `myInts.Sum` and `myStrings.Filter`.

# Functions

Expand All @@ -135,6 +135,8 @@ This will only generate `myInts.Average`, `myInts.Sum` and `myStrings.Select`.
| `Contains` | ✓ | ✓ | ✓ | | n | Check if the value exists in the slice. |
| `Extend` | ✓ | ✓ | ✓ | | n | A new slice with the elements from each slice appended to the end. |
| `Each` | ✓ | ✓ | ✓ | | n | Perform an action on each element. |
| `Filter` | ✓ | ✓ | ✓ | | n | A new slice containing only the elements that returned true from the condition. |
| `FilterNot` | ✓ | ✓ | ✓ | | n | A new slice containing only the elements that returned false from the condition. |
| `First` | ✓ | ✓ | ✓ | | 1 | The first element, or a zeroed value. |
| `FirstOr` | ✓ | ✓ | ✓ | | 1 | The first element, or a default value. |
| `Join` | ✓ | | | | n | A string from joining each of the elements. |
Expand All @@ -143,21 +145,19 @@ This will only generate `myInts.Average`, `myInts.Sum` and `myStrings.Select`.
| `Last` | ✓ | ✓ | ✓ | | 1 | The last element, or a zeroed value. |
| `LastOr` | ✓ | ✓ | ✓ | | 1 | The last element, or a default value. |
| `Len` | ✓ | ✓ | ✓ | | 1 | Number of elements. |
| `Map` | ✓ | ✓ | ✓ | | n | A new slice where each element has been mapped (transformed). |
| `Max` | ✓ | ✓ | | | n | The maximum value, or a zeroes value. |
| `Median` | | ✓ | | | n⋅log(n) | Median returns the value separating the higher half from the lower half of a data sample. |
| `Min` | ✓ | ✓ | | | n | The minimum value, or a zeroed value. |
| `Random` | ✓ | ✓ | ✓ | | 1 | Select a random element, or a zeroed value if empty. |
| `Reverse` | ✓ | ✓ | ✓ | | n | Reverse elements. |
| `Send` | ✓ | ✓ | ✓ | | n | Send all element to channel. |
| `Select` | ✓ | ✓ | ✓ | | n | A new slice containing only the elements that returned true from the condition. |
| `Sort` | ✓ | ✓ | | | n⋅log(n) | Return a new sorted slice. |
| `Sum` | | ✓ | | | n | Sum (total) of all elements. |
| `Shuffle` | ✓ | ✓ | ✓ | | n | Returns a new shuffled slice. |
| `Top` | ✓ | ✓ | ✓ | | n | Gets several elements from top(head of slice).|
| `ToStrings` | ✓ | ✓ | ✓ | | n | Transforms each element to a string. |
| `Transform` | ✓ | ✓ | ✓ | | n | A new slice where each element has been transformed. |
| `Unique` | ✓ | ✓ | | | n⋅log(n) | Return a new slice with only unique elements. |
| `Unselect` | ✓ | ✓ | ✓ | | n | A new slice containing only the elements that returned false from the condition. |
| `Values` | | | | ✓ | n | Returns all values in the map (in random order). |

# FAQ
Expand Down
7 changes: 3 additions & 4 deletions functions/select.go → functions/filter.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package functions

// Select will return a new slice containing only the elements that return
// Filter will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
// Unselect works in the opposite way as Select.
func (ss SliceType) Select(condition func(ElementType) bool) (ss2 SliceType) {
// FilterNot works in the opposite way of Filter.
func (ss SliceType) Filter(condition func(ElementType) bool) (ss2 SliceType) {
for _, s := range ss {
if condition(s) {
ss2 = append(ss2, s)
}
}

return
}
4 changes: 2 additions & 2 deletions functions/unselect.go → functions/filter_not.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package functions

// Unselect works the same as Select, with a negated condition. That is, it will
// FilterNot works the same as Filter, with a negated condition. That is, it will
// return a new slice only containing the elements that returned false from the
// condition. The returned slice may contain zero elements (nil).
func (ss SliceType) Unselect(condition func(ElementType) bool) (ss2 SliceType) {
func (ss SliceType) FilterNot(condition func(ElementType) bool) (ss2 SliceType) {
for _, s := range ss {
if !condition(s) {
ss2 = append(ss2, s)
Expand Down
6 changes: 3 additions & 3 deletions functions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ var Functions = []struct {
{"Contains", "contains.go", ForAll},
{"Each", "each.go", ForAll},
{"Extend", "extend.go", ForAll},
{"Filter", "filter.go", ForAll},
{"FilterNot", "filter_not.go", ForAll},
{"First", "first.go", ForAll},
{"FirstOr", "first_or.go", ForAll},
{"Join", "join.go", ForStrings},
Expand All @@ -37,21 +39,19 @@ var Functions = []struct {
{"Last", "last.go", ForAll},
{"LastOr", "last_or.go", ForAll},
{"Len", "len.go", ForAll},
{"Map", "map.go", ForAll},
{"Max", "max.go", ForNumbersAndStrings},
{"Median", "median.go", ForNumbers},
{"Min", "min.go", ForNumbersAndStrings},
{"Random", "random.go", ForAll},
{"Reverse", "reverse.go", ForAll},
{"Send", "send.go", ForAll},
{"Select", "select.go", ForAll},
{"Sort", "sort.go", ForNumbersAndStrings},
{"Sum", "sum.go", ForNumbers},
{"Shuffle", "shuffle.go", ForAll},
{"Top", "top.go", ForAll},
{"ToStrings", "to_strings.go", ForAll},
{"Transform", "transform.go", ForAll},
{"Unique", "unique.go", ForNumbersAndStrings},
{"Unselect", "unselect.go", ForAll},
{"Values", "values.go", ForMaps},
}

Expand Down
6 changes: 3 additions & 3 deletions functions/transform.go → functions/map.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package functions

// Transform will return a new slice where each element has been transformed.
// The number of element returned will always be the same as the input.
// Map will return a new slice where each element has been mapped (transformed).
// The number of elements returned will always be the same as the input.
//
// Be careful when using this with slices of pointers. If you modify the input
// value it will affect the original slice. Be sure to return a new allocated
// object or deep copy the existing one.
func (ss SliceType) Transform(fn func(ElementType) ElementType) (ss2 SliceType) {
func (ss SliceType) Map(fn func(ElementType) ElementType) (ss2 SliceType) {
if ss == nil {
return nil
}
Expand Down
91 changes: 45 additions & 46 deletions pie/carpointers_pie.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ func (ss carPointers) Extend(slices ...carPointers) (ss2 carPointers) {
return ss2
}

// Filter will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
// FilterNot works in the opposite way of Filter.
func (ss carPointers) Filter(condition func(*car) bool) (ss2 carPointers) {
for _, s := range ss {
if condition(s) {
ss2 = append(ss2, s)
}
}
return
}

// FilterNot works the same as Filter, with a negated condition. That is, it will
// return a new slice only containing the elements that returned false from the
// condition. The returned slice may contain zero elements (nil).
func (ss carPointers) FilterNot(condition func(*car) bool) (ss2 carPointers) {
for _, s := range ss {
if !condition(s) {
ss2 = append(ss2, s)
}
}

return
}

// First returns the first element, or zero. Also see FirstOr().
func (ss carPointers) First() *car {
return ss.FirstOr(&car{})
Expand Down Expand Up @@ -159,6 +185,25 @@ func (ss carPointers) Len() int {
return len(ss)
}

// Map will return a new slice where each element has been mapped (transformed).
// The number of elements returned will always be the same as the input.
//
// Be careful when using this with slices of pointers. If you modify the input
// value it will affect the original slice. Be sure to return a new allocated
// object or deep copy the existing one.
func (ss carPointers) Map(fn func(*car) *car) (ss2 carPointers) {
if ss == nil {
return nil
}

ss2 = make([]*car, len(ss))
for i, s := range ss {
ss2[i] = fn(s)
}

return
}

// Random returns a random element by your rand.Source, or zero
func (ss carPointers) Random(source rand.Source) *car {
n := len(ss)
Expand Down Expand Up @@ -214,20 +259,6 @@ func (ss carPointers) Send(ctx context.Context, ch chan<- *car) carPointers {
return ss
}

// Select will return a new slice containing only the elements that return
// true from the condition. The returned slice may contain zero elements (nil).
//
// Unselect works in the opposite way as Select.
func (ss carPointers) Select(condition func(*car) bool) (ss2 carPointers) {
for _, s := range ss {
if condition(s) {
ss2 = append(ss2, s)
}
}

return
}

// Shuffle returns shuffled slice by your rand.Source
func (ss carPointers) Shuffle(source rand.Source) carPointers {
n := len(ss)
Expand Down Expand Up @@ -280,35 +311,3 @@ func (ss carPointers) ToStrings(transform func(*car) string) Strings {

return result
}

// Transform will return a new slice where each element has been transformed.
// The number of element returned will always be the same as the input.
//
// Be careful when using this with slices of pointers. If you modify the input
// value it will affect the original slice. Be sure to return a new allocated
// object or deep copy the existing one.
func (ss carPointers) Transform(fn func(*car) *car) (ss2 carPointers) {
if ss == nil {
return nil
}

ss2 = make([]*car, len(ss))
for i, s := range ss {
ss2[i] = fn(s)
}

return
}

// Unselect works the same as Select, with a negated condition. That is, it will
// return a new slice only containing the elements that returned false from the
// condition. The returned slice may contain zero elements (nil).
func (ss carPointers) Unselect(condition func(*car) bool) (ss2 carPointers) {
for _, s := range ss {
if !condition(s) {
ss2 = append(ss2, s)
}
}

return
}
26 changes: 13 additions & 13 deletions pie/carpointers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ func TestCarPointers_Contains(t *testing.T) {
}
}

var carPointersSelectTests = []struct {
var carPointersFilterTests = []struct {
ss carPointers
condition func(*car) bool
expectedSelect carPointers
expectedUnselect carPointers
expectedTransform carPointers
expectedFilter carPointers
expectedFilterNot carPointers
expectedMap carPointers
}{
{
nil,
Expand All @@ -71,29 +71,29 @@ var carPointersSelectTests = []struct {
},
}

func TestCarPointers_Select(t *testing.T) {
for _, test := range carPointersSelectTests {
func TestCarPointers_Filter(t *testing.T) {
for _, test := range carPointersFilterTests {
t.Run("", func(t *testing.T) {
defer assertImmutableCarPointers(t, &test.ss)()
assert.Equal(t, test.expectedSelect, test.ss.Select(test.condition))
assert.Equal(t, test.expectedFilter, test.ss.Filter(test.condition))
})
}
}

func TestCarPointers_Unselect(t *testing.T) {
for _, test := range carPointersSelectTests {
func TestCarPointers_FilterNot(t *testing.T) {
for _, test := range carPointersFilterTests {
t.Run("", func(t *testing.T) {
defer assertImmutableCarPointers(t, &test.ss)()
assert.Equal(t, test.expectedUnselect, test.ss.Unselect(test.condition))
assert.Equal(t, test.expectedFilterNot, test.ss.FilterNot(test.condition))
})
}
}

func TestCarPointers_Transform(t *testing.T) {
for _, test := range carPointersSelectTests {
func TestCarPointers_Map(t *testing.T) {
for _, test := range carPointersFilterTests {
t.Run("", func(t *testing.T) {
defer assertImmutableCarPointers(t, &test.ss)()
assert.Equal(t, test.expectedTransform, test.ss.Transform(func(c *car) *car {
assert.Equal(t, test.expectedMap, test.ss.Map(func(c *car) *car {
return &car{
Name: strings.ToUpper(c.Name),
Color: c.Color,
Expand Down
Loading