fp

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2022 License: Apache-2.0 Imports: 3 Imported by: 0

README

brief introduction

fp is a lightweight functional programming library

pkg.go.dev

Github doc

Version compatible

  • v0.0.1

    Naming habits: adding 2 after the function name means to which means you can specify where the results are stored. The advantage is that you can add type information. You don't have to type assertions one by one.

  • v0.1.0

    This version changes the position of some parameters because it is more convenient to Coriolis fixed parameters. Put the parameters that can control the behavior on the left and the parameters that transfer data on the right. For example, reduce (resptr, fX, arr interface {}) is changed to reduce (fX, resptr, arr interface {}. Therefore, this also leads to and v0.0.1 incompatible. In addition, three functions are added: group, visit, groupreduce and mask

Future plans

In the future, it will join the goruntine pool Improve concurrency efficiency.

Add some functional functions, such as TakeWhile, Generator and Infinite list.

Documentation

Overview

简易函数式编程库 Simple functional programming library

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Filter

func Filter(fx interface{}, arr interface{}) []interface{}

fx 过滤函数, arr待处理列表。 用fx过滤arr中元素。 fx返回为真时保留,假时剔除。

FX filter function, arr pending list. Filter elements in arr with FX. If FX returns true, it will be retained and if false, it will be rejected.

Example
ids := []int{23, 90, 67, 6878, 90, 8}
fx := func(x int) bool {
	return x >= 90
}
fmt.Printf("%#v\n", Filter(fx, ids))
Output:

[]interface {}{90, 6878, 90}

func Filter2

func Filter2(fx, arr, resPtr interface{}) int

fx 过滤函数, arr待处理列表,resPtr 用于存储结果的地址,返回值为结果长度。 与Filter函数作用一样,只不过可以通过resPtr存储结果,并指定类型。 需要注意的是resPtr如果是切片或数组类型需要预留好足够空间。

FX filter function, arr pending list, resptr address used to store results, The return value is the result length. The function is the same as the filter function, except that the result can be stored through resptr and the type can be specified. It should be noted that if resptr is a slice or array type, enough space should be reserved.

Example
ids := []int{23, 90, 67, 6878, 90, 8}
fx := func(x int) bool {
	return x >= 90
}
n := Filter2(fx, ids, &ids)
fmt.Printf("%#v\n", ids[:n])
Output:

[]int{90, 6878, 90}

func Flat

func Flat(arr interface{}) []interface{}

展开arr中各个元素

Expand the elements in the arr

Example
var copyNum = func(a int) (int, int) {
	return a, a
}
arr := Fmap(copyNum, []int{7, 9})
fmt.Printf("%#v\n", arr)
fmt.Printf("%#v\n", Flat(arr))
Output:

[]interface {}{[]interface {}{7, 7}, []interface {}{9, 9}}
[]interface {}{7, 7, 9, 9}

func Flat2

func Flat2(arr interface{}, resPtr interface{}) int

展开arr中各个元素,并把结果存到resPtr。返回值为结果长度

Expand the elements in arr and save the results to resptr. The return value is the result length

Example
var copyNum = func(a int) (int, int) {
	return a, a
}
arr := Fmap(copyNum, []int{7, 9})
fmt.Printf("%#v\n", arr)
var res [6]int
n := Flat2(arr, &res)
fmt.Printf("%#v\n", res[:n])
Output:

[]interface {}{[]interface {}{7, 7}, []interface {}{9, 9}}
[]int{7, 7, 9, 9}

func Fmap

func Fmap(fx interface{}, arr interface{}) []interface{}

对arr中每个元素应用一次fx

Apply FX once to each element in the arr

Example
square := func(a int) int {
	return a * a
}
fmt.Printf("%#v\n", Fmap(square, []int{4, 7}))
Output:

[]interface {}{16, 49}

func Fmap2

func Fmap2(fx, arr, resPtr interface{}) int

对arr中每个元素应用一次fx,并把结果存到resPtr。返回值为结果长度。

Apply FX to each element in arr once and save the result in resptr. The return value is the result length.

Example
square := func(a int) int {
	return a * a
}
var res [10]int
n := Fmap2(square, []int{4, 7}, &res)
fmt.Printf("%#v\n", res[:n])
Output:

[]int{16, 49}

func Fold

func Fold(fx, arr interface{}) interface{}

对arr中的元素两两应用fx函数。 若arr长度为0返回nil,长度为1返回原数组。

Apply the FX function to every two elements in the arr. If the ARR length is 0, nil is returned, and if the ARR length is 1, the original array is returned.

Example
ids := []int{-23, 90, 67, 90, 8}
sum := func(x, y int) int {
	return x + y
}
fmt.Printf("%T : %v\n", Fold(sum, ids), Fold(sum, ids))
Output:

int : 232

func Fold2

func Fold2(fx, arr, resPtr interface{})

对arr中的元素两两应用fx函数,结果存入resPtr。 若arr长度为0返回nil,长度为1返回原数组。

Apply the FX function to two elements in arr, and store the result in resptr. If the ARR length is 0, nil is returned, and if the ARR length is 1, the original array is returned.

Example
ids := []int{-23, 90, 67, 90, 8}
sum := func(x, y int) int {
	return x + y
}
a := 0
Fold2(sum, ids, &a)
fmt.Printf("%T : %v\n", a, a)
Output:

int : 232

func Group added in v0.1.0

func Group(mask int64, arr interface{}) map[interface{}][]interface{}

根据mask对arr分组,返回map。map键的类型为byte数组。注意不是切片,golang中切片无法比较。

Group arr according to mask and return map. The type of map key is byte array. Note that it is not a slice. Slices in golang cannot be compared.

Example
// 药品信息结构体
// Drug information structure
type Drug struct {
	Name        string
	Producer    string
	Price       float32
	salesVolume int
}
data := []Drug{
	{"氟哌酸", "上海医药", 10.13, 476},
	{"氟哌酸", "智飞生物", 12.01, 312},
	{"洛贝林", "石药集团", 5.89, 621},
	{"甲硝唑", "哈药集团", 3.13, 781},
	{"洛贝林", "恒瑞", 6.54, 437},
}
// 根据药品名称分组
// Grouping by drug name
m := Group(1, data)
drugs := make([]Drug, 0, len(m))
// 不保证顺序
// Sequence is not guaranteed
k := kit.Mask(1, data[0])
for _, v := range m[k] {
	drugs = append(drugs, v.(Drug))
}
fmt.Println(drugs)
Output:

[{氟哌酸 上海医药 10.13 476} {氟哌酸 智飞生物 12.01 312}]

func GroupReduce added in v0.1.0

func GroupReduce(mask int64, reducer, res, arr interface{}) int

根据mask对arr分组,对每组列表的元素都应用一次reducer函数,并把结果存在res里。 最后返回结果列表长度。

Group the ARR according to the mask, apply the reducer function to the elements of each list, and store the results in res. Length of the last returned result list.

Example
// 药品信息结构体
// Drug information structure
type Drug struct {
	Name        string
	Producer    string
	Price       float32
	salesVolume int
}
data := []Drug{
	{"氟哌酸", "上海医药", 10.13, 476},
	{"氟哌酸", "智飞生物", 12.01, 312},
	{"洛贝林", "石药集团", 5.89, 621},
	{"甲硝唑", "哈药集团", 3.13, 781},
	{"洛贝林", "恒瑞", 6.54, 437},
}
// 药品销售额结构体
// Drug sales structure
type SaleOfDrug struct {
	Name        string
	TotalAmount float32
}
// 统计函数
// Statistical function
acc := func(s *SaleOfDrug, d Drug) {
	if s == nil {
		// 统计第一个时创建一个 SaleOfDrug
		// Create a SaleOfDrug when counting the first
		s = &SaleOfDrug{
			d.Name,
			d.Price * float32(d.salesVolume),
		}
	} else {
		(*s).Name = d.Name
		(*s).TotalAmount += d.Price * float32(d.salesVolume)
	}
}
res := make([]SaleOfDrug, 30)
n := GroupReduce(1, acc, &res, data)
fmt.Println(res[:n])
Output:

[{氟哌酸 8569} {洛贝林 6515.67} {甲硝唑 2444.53}]

func Reduce

func Reduce(fx, resPtr, arr interface{})

fx函数应接收两个参数,一个为resPtr,另一个为arr中的元素。 该函数遍历arr,并调用fx函数。

The FX function should take two arguments, one resptr and the other an element in arr. This function traverses the ARR and calls the FX function.

Example
box := make([]float64, 0, 10)
data := []float64{5, 76, 67, 69, 70, -7, 8}
collect := func(r *[]float64, b float64) {
	*r = append(*r, b)
}
Reduce(collect, &box, data)
fmt.Printf("%#v\n", box)
Output:

[]float64{5, 76, 67, 69, 70, -7, 8}

func UnzipWith

func UnzipWith(fx, arr interface{}) ([]interface{}, []interface{})

通过fx,分裂列表arr。

Split the list arr through FX.

Example
var copyNum = func(a int) (int, int) {
	return a, a
}
a, b := UnzipWith(copyNum, []int{7, -2, 0})
fmt.Printf("%#v\n", a)
fmt.Printf("%#v\n", b)
Output:

[]interface {}{7, -2, 0}
[]interface {}{7, -2, 0}

func UnzipWith2

func UnzipWith2(fx, arr, resPtr1, resPtr2 interface{}) int

通过fx,分裂列表arr,并把结果存入 resPtr1, resPtr2。

Split the list arr through FX and store the results in resptr1 and resptr2.

Example
var copyNum = func(a int) (int, int) {
	return a, a
}
var a, b [8]int
n := UnzipWith2(copyNum, []int{7, -2, 0}, &a, &b)
fmt.Printf("%#v\n", a[:n])
fmt.Printf("%#v\n", b[:n])
Output:

[]int{7, -2, 0}
[]int{7, -2, 0}

func ZipWith

func ZipWith(fx, arr1, arr2 interface{}) []interface{}

通过fx函数合并arr1和arr2

Merge Arr1 and arr2 through FX function

Example
type Student struct {
	id   int
	name string
}
NewStudent := func(id int, name string) Student {
	return Student{
		id:   id,
		name: name,
	}
}
names, ids := []string{"Jack", "John"}, []int{7, 3, 11}
fmt.Printf("%#v\n", ZipWith(NewStudent, ids, names))
Output:

[]interface {}{fp.Student{id:7, name:"Jack"}, fp.Student{id:3, name:"John"}}

func ZipWith2

func ZipWith2(fx, arr1, arr2, resPtr interface{}) int

通过fx函数合并arr1和arr2,并把结果存到resPtr。返回值为结果长度

Merge Arr1 and arr2 through the FX function and save the results in resptr. The return value is the result length.

Example
type Student struct {
	id   int
	name string
}
NewStudent := func(id int, name string) Student {
	return Student{
		id:   id,
		name: name,
	}
}
names, ids := []string{"Jack", "John"}, []int{7, 3, 11}
stus := make([]Student, 10)
n := ZipWith2(NewStudent, ids, names, &stus)
fmt.Printf("%#v\n", stus[:n])
Output:

[]fp.Student{fp.Student{id:7, name:"Jack"}, fp.Student{id:3, name:"John"}}

Types

type HalfFunc

type HalfFunc func(...interface{}) interface{}

半函数。

Function with partial parameters fixed.

func Currying

func Currying(fx interface{}, p ...interface{}) HalfFunc

p 为参数列表,fx 为函数。 返回一个HalfFunc。 Currying可以固定一个函数的前几个参数。

P is the parameter list and FX is the function. Returns a HalfFunc. Currying can fix the first few parameters of a function.

Example
add2 := func(a, b int) int {
	return a + b
}
add1 := Currying(add2, 7)
fmt.Printf("%T : %v\n", add1(2), add1(2))
// 连续柯里化
// Compound Currying
res := Currying(add1, 3)
fmt.Printf("%T : %v\n", res(), res())
// 固定多个参数
// Fix multiple parameters
res2 := Currying(add2, 7, 9)
fmt.Printf("%T : %v\n", res2(), res2())
// 和Fmap复合使用
// Combined with fmap
fmt.Printf("%#v\n", Fmap(add1, []int{4, -3}))
// 多返回值
// Multiple return values
swap2 := func(a, b int) (int, int) {
	return b, a
}
swap1 := Currying(swap2, 7)
swap0 := Currying(swap1, 3)
fmt.Printf("%#v\n", swap0())
Output:

int : 9
int : 10
int : 16
[]interface {}{11, 4}
[]interface {}{3, 7}

func Pipe

func Pipe(fx1, fx2 interface{}) HalfFunc

组合两个函数,返回一个 HalfFunc。 返回的函数会把收到的参数尽量给fx1。 fx1的结果和余下的参数作为fx2的参数。 最终返回fx2的结果。

Combine two functions to return a HalfFunc. The returned function will give the received parameters to FX1 as much as possible. The result of FX1 and the remaining parameters are the parameters of FX2. Finally, the result of FX2 is returned.

Example
var copyNum = func(a int) (int, int) {
	return a, a
}
add2 := func(a, b int) int {
	return a + b
}
// 部分参数作为第一个函数的参数
// Some parameters are used as parameters of the first function
square := func(a int) int {
	return a * a
}
f1 := Pipe(square, add2)
fmt.Printf("%#v\n", f1(-2, 7))
// 全部参数作为第一个函数的参数
// All parameters are the parameters of the first function
f2 := Pipe(copyNum, func(a, b int) int {
	return a * b
})
fmt.Printf("%#v\n", f2(8))
Output:

11
64

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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