thoas / go-funk
A modern Go utility library which provides helpers (map, find, contains, filter, ...)
AI Architecture Analysis
This repository is indexed by RepoMind. By analyzing thoas/go-funk in our AI interface, you can instantly generate complete architecture diagrams, visualize control flows, and perform automated security audits across the entire codebase.
Our Agentic Context Augmented Generation (Agentic CAG) engine loads full source files into context on-demand, avoiding the fragmentation of traditional RAG systems. Ask questions about the architecture, dependencies, or specific features to see it in action.
Repository Overview (README excerpt)
Crawler viewgo-funk ======= .. image:: https://secure.travis-ci.org/thoas/go-funk.svg?branch=master :alt: Build Status :target: http://travis-ci.org/thoas/go-funk .. image:: https://godoc.org/github.com/thoas/go-funk?status.svg :alt: GoDoc :target: https://pkg.go.dev/github.com/thoas/go-funk .. image:: https://goreportcard.com/badge/github.com/thoas/go-funk :alt: Go report :target: https://goreportcard.com/report/github.com/thoas/go-funk go-funk is a modern Go library based on reflect_. 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 go-funk come from internal use cases. You can also find typesafe implementation in the godoc_. Why this name? -------------- Long story, short answer because func is a reserved word in Go, I wanted something similar. Initially this project was named fn I don't need to explain why that was a bad idea for french speakers :) Let's funk ! .. image:: https://media.giphy.com/media/3oEjHQKtDXpeGN9rW0/giphy.gif slice • map -> map • slice -> map • slice -> slice .. code-block:: go 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.FlatMap ............ Manipulates an iteratee (map, slice) and transforms it to to a flattened collection of another type: • map -> slice • slice -> slice .. code-block:: go 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.Get ........ Retrieves the value at path of struct(s) or map(s). .. code-block:: go 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 funk.Get also support map values: .. code-block:: go 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, "Labels": map[string]interface{} { "example.com/hello": "world", }, } // 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 funk.Get(foo2, ) // world funk.Get also handles nil values: .. code-block:: go 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.GetOrElse .............. Retrieves the value of the pointer or default. .. code-block:: go str := "hello world" GetOrElse(&str, "foobar") // string{"hello world"} GetOrElse(str, "foobar") // string{"hello world"} GetOrElse(nil, "foobar") // string{"foobar"} funk.Set ........ Set value at a path of a struct .. code-block:: go 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.MustSet ............ Short hand for funk.Set if struct does not contain interface{} field type to discard errors. funk.Prune .......... Copy a struct with only selected fields. Slice is handled by pruning all elements. .. code-block:: go 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}, // } funk.PruneByTag .......... Same functionality as funk.Prune, but uses struct tags instead of struct field names. funk.Keys ......... Creates an array of the own enumerable map keys or struct field names. .. code-block:: go funk.Keys(map[string]int{"one": 1, "two": 2}) // []string{"one", "two"} (iteration order is not guaranteed) foo := &Foo{ ID: 1, FirstName: "Dark", LastName: "Vador", Age: 30, } funk.Keys(foo) // []string{"ID", "FirstName", "LastName", "Age"} (iteration order is not guaranteed) funk.Values ........... Creates an array of the own enumerable map values or struct field values. .. code-block:: go funk.Values(map[string]int{"one": 1, "two": 2}) // []int{1, 2} (iteration or…