pipe

package module
v0.0.0-...-d28c344 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2014 License: MIT Imports: 3 Imported by: 0

README

pipe Build Status

All the usual functional ways to work with sequences of data in Go.

Usage

import "github.com/paulbellamy/pipe"

Why

Because a bit of functional programming can make code a lot more readable and expressive.

Should I Use This?

It depends. It is pretty heavy on runtime-reflection. Are you ok with sacrificing some of Go's static-type-checking and compile-time safety for more expressiveness?

Documentation

Contributing

Contributions are welcome via pull requests.

License

Copyright © 2014 Paul Bellamy

Released under the MIT License.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DropChan

func DropChan(num int, input interface{}) interface{}

DropChan is of type: func(num int, input chan T) chan T. Drop a given number of items from the input chan. After that number has been dropped, the rest are passed straight through.

Example
in := make(chan int, 10)
out := DropChan(3, in).(chan int)

for i := 0; i < 5; i++ {
	in <- i
}

fmt.Println(<-out)
fmt.Println(<-out)
Output:

3
4

func DropWhileChan

func DropWhileChan(fn, input interface{}) interface{}

DropWhileChan is of type: func(fn func(T) bool, input chan T) chan T. Drop the items from the input chan until the given function returns true. After that, the rest are passed straight through.

Example
in := make(chan int, 5)

lessThan := func(x int) func(int) bool {
	return func(item int) bool {
		return item < 3
	}
}

out := DropWhileChan(lessThan(3), in).(chan int)

in <- 1
in <- 2
in <- 3
in <- 2

fmt.Println(<-out)
fmt.Println(<-out)
Output:

3
2

func DropWhileSlice

func DropWhileSlice(fn, input interface{}) interface{}

DropWhileSlice is of type: func(fn func(T) bool, input []T) []T. Drop the items from the input slice until the given function returns true. After that, the rest are passed straight through.

Example
in := []int{1, 2, 3, 2}

lessThan := func(x int) func(int) bool {
	return func(item int) bool {
		return item < 3
	}
}

out := DropWhileSlice(lessThan(3), in).([]int)

fmt.Println(out)
Output:

[3 2]

func FieldByName

func FieldByName(name string) func(interface{}) interface{}

FieldByName is a helper for fetching a named field from a struct. It is useful in conjunction with Map, to retrieve many values at once.

Example
type customer struct {
	Name string
	Age  int
}

customers := []customer{{"Alice", 26}, {"Bob", 46}, {"Yousef", 37}}

names := MapSlice(FieldByName("Name"), customers)
ages := MapSlice(FieldByName("Age"), customers)

fmt.Println(names)
fmt.Println(ages)
Output:

[Alice Bob Yousef]
[26 46 37]

func FilterChan

func FilterChan(fn, input interface{}) interface{}

FilterChan is of type: func(fn func(T) bool, input chan T) chan T. Apply a filtering function to a chan, which will only pass through items when the filter func returns true.

Example
even := func(item int) bool {
	return (item % 2) == 0
}

numbers := make(chan int)
out := FilterChan(even, numbers).(chan int)

go func() {
	numbers <- 1
	numbers <- 2
	numbers <- 3
	numbers <- 4
	numbers <- 5
	numbers <- 6
	numbers <- 7
	numbers <- 8
	numbers <- 9
	numbers <- 10
	close(numbers)
}()

// Print each output
for result := range out {
	fmt.Println(result)
}
Output:

2
4
6
8
10

func FilterSlice

func FilterSlice(fn, input interface{}) interface{}

FilterSlice is of type: func(fn func(T) bool, input []T) []T. Apply a filtering function to a slice, which will only pass through items when the filter func returns true.

Example
even := func(item int) bool {
	return (item % 2) == 0
}

numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
out := FilterSlice(even, numbers).([]int)

fmt.Println(out)
Output:

[2 4 6 8 10]

func FlattenChan

func FlattenChan(input interface{}) interface{}

FlattenChan is of type: func(input chan []T) chan T. Takes a chan of arrays, and concatenates them together, putting each element onto the output chan. After input is closed, output is also closed. If input is chan T instead of type chan []T, then this is a no-op.

Example
in := make(chan []int, 5)
out := FlattenChan(in).(chan int)

in <- []int{1, 2}
in <- []int{3, 4}
in <- []int{5, 6}
close(in)

for result := range out {
	fmt.Println(result)
}
fmt.Println("Closed!")
Output:

1
2
3
4
5
6
Closed!

func FlattenSlice

func FlattenSlice(input interface{}) interface{}

FlattenSlice is of type: func(input [][]T) []T. Takes a chan of arrays, and concatenates them together, putting each element onto the output chan. After input is closed, output is also closed. If input is []T instead of type [][]T, then this is a no-op.

Example
in := [][]int{{1, 2}, {3, 4}, {5}}
out := FlattenSlice(in).([]int)

for _, result := range out {
	fmt.Println(result)
}
Output:

1
2
3
4
5

func ForEachChan

func ForEachChan(fn, input interface{})

ForEachChan is of type: func(fn func(T), input chan T) Execute a function for each item. Useful for monitoring, logging, or causing some side-effect. Returns nothing

Example
// Declare a chan of some things
places := make(chan string, 5)

places <- "Grantchester"
places <- "Cambridge"
places <- "Prague"
close(places)

ForEachChan(fmt.Println, places)
Output:

Grantchester
Cambridge
Prague

func ForEachSlice

func ForEachSlice(fn, input interface{})

ForEachSlice is of type: func(fn func(T), input []T). Execute a function for each item. Returns nothing.

Example
// Declare a slice of some things
places := []string{"Grantchester", "Cambridge", "Prague"}

ForEachSlice(fmt.Println, places)
Output:

Grantchester
Cambridge
Prague

func IterateChan

func IterateChan(fn interface{}, initialArgs ...interface{}) interface{}

IterateChan is of type: func(fn func(T) T, initialArgs ...T) chan T. Returns a channel with the values of x, fn(x), fn(fn(x)), etc... fn can take multiple arguments, and return multiple values, but the types and counts of arguments and return values must match. Only the first return value of each call to fn will be printed.

Example
fib := func(f, s int) (int, int) {
	return s, f + s
}

out := IterateChan(fib, 0, 1).(chan int)

for i := 0; i < 10; i++ {
	fmt.Println(<-out)
}
Output:

0
1
1
2
3
5
8
13
21
34

func MapCatChan

func MapCatChan(fn, input interface{}) interface{}

MapCatChan is of type: func(fn func(T) []U, input chan T) chan U. It returns a chan which receives fn(item) for each item in input.

Example
printer := func(item int) []string {
	return []string{fmt.Sprintf("%d", item), fmt.Sprintf("%.3d", item)}
}
in := make(chan int, 5)
out := MapCatChan(printer, in).(chan string)

go func() {
	in <- 1
	in <- 2
	in <- 3
	close(in)
}()

for result := range out {
	fmt.Println(result)
}
fmt.Println("Closed!")

// Output
// 1
// 001
// 2
// 002
// 3
// 003
// Closed!
Output:

func MapCatSlice

func MapCatSlice(fn, input interface{}) interface{}

MapCatSlice is of type: func(fn func(T) []U, input []T) []U. It returns a slice with fn(item) for each item in input.

Example
printer := func(item int) []string {
	return []string{fmt.Sprintf("%d", item), fmt.Sprintf("%.3d", item)}
}
in := []int{7, 4, 5}
result := MapCatSlice(printer, in).([]string)

for _, item := range result {
	fmt.Println(item)
}
Output:

7
007
4
004
5
005

func MapChan

func MapChan(fn, input interface{}) interface{}

MapChan is of type: func(fn func(T) U, input chan T) chan U. It returns a chan which receives fn(item) for each item in input.

Example
// Declare a chan of some things
numbers := make(chan int)

// function to apply
square := func(x int) int {
	return x * x
}

// Create a new chan which applies a function to the original
squares := MapChan(square, numbers).(chan int)

// Put some numbers in the original chan
go func() {
	numbers <- 1
	numbers <- 2
	numbers <- 3
}()

fmt.Println(<-squares)
fmt.Println(<-squares)
fmt.Println(<-squares)
Output:

1
4
9

func MapSlice

func MapSlice(fn, input interface{}) interface{}

MapSlice is of type: func(fn func(T) U, input []T) []U. It returns a slice of fn(item) for each item in input.

Example
package main

import (
	"fmt"
)

type place struct {
	name       string
	population int
}

func statusByPopulation(p place) string {
	switch {
	case p.population > 1000000:
		return "City"
	case p.population > 5000:
		return "Town"
	default:
		return "Village"
	}
}

func main() {
	// Declare a slice of some things
	places := []place{
		{"Grantchester", 552},
		{"Cambridge", 117900},
		{"Prague", 1188126},
	}

	sizes := MapSlice(statusByPopulation, places).([]string)

	fmt.Println(sizes)

}
Output:

[Village Town City]

func OntoChan

func OntoChan(input interface{}) interface{}

OntoChan is of type: func(input []T) chan T. Puts the elements of the input collection onto a channel, which is then closed.

Example
in := []int{0, 1, 2, 3, 4}
out := OntoChan(in).(chan int)

for x := range out {
	fmt.Println(x)
}
fmt.Println("Closed!")
Output:

0
1
2
3
4
Closed!

func ReduceChan

func ReduceChan(fn, initial, input interface{}) interface{}

ReduceChan is of type: func(fn func(accumulator U, item T) U, initial U, input chan T) U. It accumulates the result of the reduce function being called on each item, then when the input channel is closed, return the result.

Example
// Declare a slice of some things
chars := make(chan string)

// Function to apply
concat := func(a, b string) string {
	return fmt.Sprintf("%s%s", a, b)
}

// Push some values into the input
go func() {
	chars <- "a"
	chars <- "b"
	chars <- "c"
	close(chars)
}()

sum := ReduceChan(concat, "", chars).(string)

fmt.Println(sum)
Output:

abc

func ReduceSlice

func ReduceSlice(fn, initial, input interface{}) interface{}

ReduceSlice is of type: func(fn func(accumulator U, item T) U, initial U, input []T) U. It accumulates the result of the fn function being called on each item, with the last value being returned.

Example
// Declare a slice of some things
chars := []string{"a", "b", "c"}

// Function to apply
concat := func(a, b string) string {
	return fmt.Sprintf("%s%s", a, b)
}

sum := ReduceSlice(concat, "", chars).(string)

fmt.Println(sum)
Output:

abc

func RepeatedlyChan

func RepeatedlyChan(fn interface{}) interface{}

IterateChan is of type: func(fn func() T) chan T. Take some function 'fn' (presumably with some side-effect). It is repeatedly called, and the return values put onto the returned channel.

Example
count := -1
out := RepeatedlyChan(func() int {
	count++
	return count
}).(chan int)

for i := 0; i < 3; i++ {
	fmt.Println(<-out)
}
Output:

0
1
2

func TakeChan

func TakeChan(num int, input interface{}) interface{}

TakeChan is of type: func(num int, input chan T) chan T. Accept only the given number of items from the input chan. After that number has been received, all input messages will be ignored and the output channel will be closed.

Example
in := make(chan int, 10)
out := TakeChan(3, in).(chan int)

for i := 0; i < 5; i++ {
	in <- i
}

for result := range out {
	fmt.Println(result)
}
fmt.Println("Closed!")
Output:

0
1
2
Closed!

func TakeWhileChan

func TakeWhileChan(fn, input interface{}) interface{}

TakeWhileChan is of type: func(fn func(T) bool, input chan T) chan T. Accept items from the input chan until the given function returns false. After that, all input messages will be ignored and the output channel will be closed.

Example
in := make(chan int, 5)
out := TakeWhileChan(func(item int) bool {
	return item != 5
}, in).(chan int)

in <- 7
in <- 4
in <- 5
in <- 6

for result := range out {
	fmt.Println(result)
}

fmt.Println("Closed!")
Output:

7
4
Closed!

func TakeWhileSlice

func TakeWhileSlice(fn, input interface{}) interface{}

TakeWhileSlice is of type: func(fn func(T) bool, input []T) []T. Accept items from the input slice until the given function returns false. After that, the rest are passed straight through.

Example
in := []int{7, 4, 5, 6}
out := TakeWhileSlice(func(item int) bool {
	return item != 5
}, in).([]int)

fmt.Println(out)
Output:

[7 4]

func ZipChan

func ZipChan(input interface{}, others ...interface{}) interface{}

ZipChan is of type: func(input chan T, others ...chan T) chan []T. Group each message from the input channel with it's corresponding message(s) from the other channel(s). This will block on the first channel until it receives a message, then block on the second until it gets one from there. At that point an array containing both will be sent to the output channel.

Example
other := make(chan int, 5)
in := make(chan int, 5)
out := ZipChan(in, other).(chan []int)

in <- 5
in <- 10
in <- 20
other <- 6
other <- 11
close(other)

for result := range out {
	fmt.Println(result)
}
fmt.Println("Closed!")
Output:

[5 6]
[10 11]
Closed!

func ZipSlice

func ZipSlice(input interface{}, others ...interface{}) interface{}

ZipSlice is of type: func(input []T, others ...[]T) [][]T. Group each item from the input with it's corresponding item(s) from the others.

Example
in := []int{5, 10, 20}
other := []int{6, 11}
out := ZipSlice(in, other).([][]int)

for _, result := range out {
	fmt.Println(result)
}
Output:

[5 6]
[10 11]

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL