在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:thoas/go-funk开源软件地址:https://github.com/thoas/go-funk开源编程语言:Go 100.0%开源软件介绍:go-funk
Generic helpers rely on reflect, be careful this code runs exclusively on runtime so you must have a good test suite. These helpers have started as an experiment to learn reflect. It may look like lodash in some aspects but
it will have its own roadmap. lodash is an awesome library with a lot of work behind it, all features included in
You can also find typesafe implementation in the godoc. Why this name?Long story, short answer because Initially this project was named Let's <3 Installationgo get github.com/thoas/go-funk Usageimport "github.com/thoas/go-funk" These examples will be based on the following data model: type Foo struct {
ID int
FirstName string `tag_name:"tag 1"`
LastName string `tag_name:"tag 2"`
Age int `tag_name:"tag 3"`
}
func (f Foo) TableName() string {
return "foo"
} With fixtures: f := &Foo{
ID: 1,
FirstName: "Foo",
LastName: "Bar",
Age: 30,
} You can import import "github.com/thoas/go-funk" funk.ContainsReturns true if an element is present in a iteratee (slice, map, string). One frustrating thing in Go is to implement func ContainsInt(s []int, e int) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
} this can be replaced by // slice of string
funk.Contains([]string{"foo", "bar"}, "bar") // true
// slice of Foo ptr
funk.Contains([]*Foo{f}, f) // true
funk.Contains([]*Foo{f}, func (foo *Foo) bool {
return foo.ID == f.ID
}) // true
funk.Contains([]*Foo{f}, nil) // false
b := &Foo{
ID: 2,
FirstName: "Florent",
LastName: "Messa",
Age: 28,
}
funk.Contains([]*Foo{f}, b) // false
// string
funk.Contains("florent", "rent") // true
funk.Contains("florent", "foo") // false
// even map
funk.Contains(map[int]string{1: "Florent"}, 1) // true
funk.Contains(map[int]string{1: "Florent"}, func(key int, name string) bool {
return key == 1 // or `name == "Florent"` for the value type
}) // true see also, typesafe implementations: ContainsInt, ContainsInt64, ContainsFloat32, ContainsFloat64, ContainsString funk.IntersectReturns the intersection between two collections. funk.Intersect([]int{1, 2, 3, 4}, []int{2, 4, 6}) // []int{2, 4}
funk.Intersect([]string{"foo", "bar", "hello", "bar"}, []string{"foo", "bar"}) // []string{"foo", "bar"} see also, typesafe implementations: IntersectString funk.DifferenceReturns the difference between two collections. funk.Difference([]int{1, 2, 3, 4}, []int{2, 4, 6}) // []int{1, 3}, []int{6}
funk.Difference([]string{"foo", "bar", "hello", "bar"}, []string{"foo", "bar"}) // []string{"hello"}, []string{} see also, typesafe implementations: DifferenceString funk.IndexOfGets the index at which the first occurrence of a value is found in an array or return -1 if the value cannot be found. // slice of string
funk.IndexOf([]string{"foo", "bar"}, "bar") // 1
funk.IndexOf([]string{"foo", "bar"}, func(value string) bool {
return value == "bar"
}) // 1
funk.IndexOf([]string{"foo", "bar"}, "gilles") // -1 see also, typesafe implementations: IndexOfInt, IndexOfInt64, IndexOfFloat32, IndexOfFloat64, IndexOfString funk.LastIndexOfGets the index at which the last occurrence of a value is found in an array or return -1 if the value cannot be found. // slice of string
funk.LastIndexOf([]string{"foo", "bar", "bar"}, "bar") // 2
funk.LastIndexOf([]string{"foo", "bar"}, func(value string) bool {
return value == "bar"
}) // 2
funk.LastIndexOf([]string{"foo", "bar"}, "gilles") // -1 see also, typesafe implementations: LastIndexOfInt, LastIndexOfInt64, LastIndexOfFloat32, LastIndexOfFloat64, LastIndexOfString funk.ToMapTransforms a slice or an array of structs to a map based on a f := &Foo{
ID: 1,
FirstName: "Gilles",
LastName: "Fabio",
Age: 70,
}
b := &Foo{
ID: 2,
FirstName: "Florent",
LastName: "Messa",
Age: 80,
}
results := []*Foo{f, b}
mapping := funk.ToMap(results, "ID") // map[int]*Foo{1: f, 2: b} funk.ToSetTransforms an array or a slice to a set (a map with zero-size values). f := Foo{
ID: 1,
FirstName: "Gilles",
LastName: "Fabio",
Age: 70,
}
b := Foo{
ID: 2,
FirstName: "Florent",
LastName: "Messa",
Age: 80,
}
mapping := funk.ToSet([]Foo{f, b}) // map[Foo]stuct{}{f: struct{}{}, b: struct{}{}}
mapping := funk.ToSet([4]int{1, 1, 2, 2}) // map[int]struct{}{1: struct{}{}, 2: struct{}{}} funk.FilterFilters a slice based on a predicate. r := funk.Filter([]int{1, 2, 3, 4}, func(x int) bool {
return x%2 == 0
}) // []int{2, 4} see also, typesafe implementations: FilterInt, FilterInt64, FilterFloat32, FilterFloat64, FilterString funk.ReduceReduces an iteratee based on an accumulator function or operation rune for numbers. // Using operation runes. '+' and '*' only supported.
r := funk.Reduce([]int{1, 2, 3, 4}, '+', float64(0)) // 10
r := funk.Reduce([]int{1, 2, 3, 4}, '*', 1) // 24
// Using accumulator function
r := funk.Reduce([]int{1, 2, 3, 4}, func(acc float64, num int) float64 {
return acc + float64(num)
}, float64(0)) // 10
r := funk.Reduce([]int{1, 2, 3, 4}, func(acc string, num int) string {
return acc + fmt.Sprint(num)
}, "") // "1234" funk.FindFinds an element in a slice based on a predicate. r := funk.Find([]int{1, 2, 3, 4}, func(x int) bool {
return x%2 == 0
}) // 2 see also, typesafe implementations: FindInt, FindInt64, FindFloat32, FindFloat64, FindString funk.MapManipulates an iteratee (map, slice) and transforms it to another type:
r := funk.Map([]int{1, 2, 3, 4}, func(x int) int {
return x * 2
}) // []int{2, 4, 6, 8}
r := funk.Map([]int{1, 2, 3, 4}, func(x int) string {
return "Hello"
}) // []string{"Hello", "Hello", "Hello", "Hello"}
r = funk.Map([]int{1, 2, 3, 4}, func(x int) (int, int) {
return x, x
}) // map[int]int{1: 1, 2: 2, 3: 3, 4: 4}
mapping := map[int]string{
1: "Florent",
2: "Gilles",
}
r = funk.Map(mapping, func(k int, v string) int {
return k
}) // []int{1, 2}
r = funk.Map(mapping, func(k int, v string) (string, string) {
return fmt.Sprintf("%d", k), v
}) // map[string]string{"1": "Florent", "2": "Gilles"} funk.FlatMapManipulates an iteratee (map, slice) and transforms it to to a flattened collection of another type:
r := funk.FlatMap([][]int{{1, 2}, {3, 4}}, func(x []int) []int {
return append(x, 0)
}) // []int{1, 2, 0, 3, 4, 0}
mapping := map[string][]int{
"Florent": {1, 2},
"Gilles": {3, 4},
}
r = funk.FlatMap(mapping, func(k string, v []int) []int {
return v
}) // []int{1, 2, 3, 4} funk.GetRetrieves the value at path of struct(s) or map(s). var bar *Bar = &Bar{
Name: "Test",
Bars: []*Bar{
&Bar{
Name: "Level1-1",
Bar: &Bar{
Name: "Level2-1",
},
},
&Bar{
Name: "Level1-2",
Bar: &Bar{
Name: "Level2-2",
},
},
},
}
var foo *Foo = &Foo{
ID: 1,
FirstName: "Dark",
LastName: "Vador",
Age: 30,
Bar: bar,
Bars: []*Bar{
bar,
bar,
},
}
funk.Get([]*Foo{foo}, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"}
funk.Get(foo, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"}
funk.Get(foo, "Bar.Name") // Test
bar := map[string]interface{}{
"Name": "Test",
}
foo1 := map[string]interface{}{
"ID": 1,
"FirstName": "Dark",
"LastName": "Vador",
"Age": 30,
"Bar": bar,
}
foo2 := &map[string]interface{}{
"ID": 1,
"FirstName": "Dark",
"LastName": "Vador",
"Age": 30,
} // foo2.Bar is nil
funk.Get(bar, "Name") // "Test"
funk.Get([]map[string]interface{}{foo1, foo2}, "Bar.Name") // []string{"Test"}
funk.Get(foo2, "Bar.Name") // nil
bar := &Bar{
Name: "Test",
}
foo1 := &Foo{
ID: 1,
FirstName: "Dark",
LastName: "Vador",
Age: 30,
Bar: bar,
}
foo2 := &Foo{
ID: 1,
FirstName: "Dark",
LastName: "Vador",
Age: 30,
} // foo2.Bar is nil
funk.Get([]*Foo{foo1, foo2}, "Bar.Name") // []string{"Test"}
funk.Get(foo2, "Bar.Name") // nil funk.GetOrElseRetrieves the value of the pointer or default. str := "hello world"
GetOrElse(&str, "foobar") // string{"hello world"}
GetOrElse(str, "foobar") // string{"hello world"}
GetOrElse(nil, "foobar") // string{"foobar"} funk.SetSet value at a path of a struct var bar Bar = Bar{
Name: "level-0",
Bar: &Bar{
Name: "level-1",
Bars: []*Bar{
{Name: "level2-1"},
{Name: "level2-2"},
},
},
}
_ = Set(&bar, "level-0-new", "Name")
fmt.Println(bar.Name) // "level-0-new"
MustSet(&bar, "level-1-new", "Bar.Name")
fmt.Println(bar.Bar.Name) // "level-1-new"
Set(&bar, "level-2-new", "Bar.Bars.Name")
fmt.Println(bar.Bar.Bars[0].Name) // "level-2-new"
fmt.Println(bar.Bar.Bars[1].Name) // "level-2-new" funk.MustSetShort hand for funk.Set if struct does not contain interface{} field type to discard errors. funk.PruneCopy a struct with only selected fields. Slice is handled by pruning all elements. bar := &Bar{
Name: "Test",
}
foo1 := &Foo{
ID: 1,
FirstName: "Dark",
LastName: "Vador",
Bar: bar,
}
pruned, _ := Prune(foo1, []string{"FirstName", "Bar.Name"})
// *Foo{
// ID: 0,
// FirstName: "Dark",
// LastName: "",
// Bar: &Bar{Name: "Test},
// } |