{"id":13412906,"url":"https://github.com/tobyhede/go-underscore","last_synced_at":"2025-05-16T05:07:37.039Z","repository":{"id":41309089,"uuid":"21420279","full_name":"tobyhede/go-underscore","owner":"tobyhede","description":" Helpfully Functional Go -  A useful collection of Go utilities. Designed for programmer happiness. ","archived":false,"fork":false,"pushed_at":"2023-02-28T05:58:57.000Z","size":291,"stargazers_count":1301,"open_issues_count":4,"forks_count":61,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-05-13T22:06:20.182Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tobyhede.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2014-07-02T10:27:16.000Z","updated_at":"2025-04-05T19:33:05.000Z","dependencies_parsed_at":"2024-01-08T15:02:44.817Z","dependency_job_id":null,"html_url":"https://github.com/tobyhede/go-underscore","commit_stats":{"total_commits":82,"total_committers":7,"mean_commits":"11.714285714285714","dds":0.07317073170731703,"last_synced_commit":"d9938588b530e1c115a9adc30a63b8ee4903bc1c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobyhede%2Fgo-underscore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobyhede%2Fgo-underscore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobyhede%2Fgo-underscore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tobyhede%2Fgo-underscore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tobyhede","download_url":"https://codeload.github.com/tobyhede/go-underscore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254471060,"owners_count":22076585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T20:01:30.884Z","updated_at":"2025-05-16T05:07:32.029Z","avatar_url":"https://github.com/tobyhede.png","language":"Go","readme":"Underscore.go\n==========================================\n\nMove Fast; Optimize Late\n------------------------------------------\n\nA useful collection of Go utilities. Designed for programmer happiness.\n\nTL;DR Sort-of like underscore.js, but for Go\n\nAPI Documentation\n------------------------------------------\n[GoDoc is WorkInProgress](https://godoc.org/github.com/tobyhede/go-underscore)\n\n\n:warning: Warning\n------------------------------------------\nThis package is in heavy flux at the moment as I work to incorporate feedback from various sources.\n\n\n:squirrel: Todo\n------------------------------------------\n\n- [ ] godoc\n- [ ] contains\n- [ ] indexOf\n- [ ] worker pools\n- [x] parallel each\n- [x] parallel map with worker pool\n- [x] refactor to make functions first parameter (eg Each func(func(A), []A))\n- [x] handle maps \u0026 slices\n- [x] all\n- [x] any\n- [x] none\n\n\n\n------------------------------------------\n* [Notes on Typed Functions](#typed)\n* [Any](#any)\n* [Each](#each)\n* [Every](#every)\n* [Map](#map)\n* [None](#none)\n\n\n### \u003ca name=\"typed\"\u003e\u003c/a\u003eTyped Functions ###\n---------------------------------------------------------------------------\n\n\n### \u003ca name=\"any\"\u003e\u003c/a\u003eAny ###\n---------------------------------------------------------------------------\n\n\n### \u003ca name=\"each\"\u003e\u003c/a\u003eEach ###\n---------------------------------------------------------------------------\n\nEach func(func(A int), []A)\nEach func(func(A B), []A)\n\n\nApplies the given iterator function to each element of a collection (slice or map).\n\nIf the collection is a Slice, the iterator function arguments are *value, index*\n\nIf the collection is a Map, the iterator function arguments are *value, key*\n\nEachP is a Parallel implementation of Each and *concurrently* applies the given iterator function to each element of a collection (slice or map).\n\n\n``` go\n  // var Each func(func(value interface{}, i interface{}), interface{})\n\n  var buffer bytes.Buffer\n\n  fn := func(s, i interface{}) {\n    buffer.WriteString(s.(string))\n  }\n\n  s := []string{\"a\", \"b\", \"c\", \"d\", \"e\"}\n  Each(fn, s)\n\n  expect := \"abcde\"\n\n  e := un.Each(fn, s)\n\n  fmt.Printf(\"%#v\\n\", e) //\"abcde\"\n```\n\nTyped Each can be defined using a function type and the *MakeEach* helper.\n\nUsing a Typed Slice\n\n``` go\n  var EachInt func(func(value, i int), []int)\n  MakeEach(\u0026EachInt)\n\n  var sum int\n\n  fn := func(v, i int) {\n    sum += v\n  }\n\n  i := []int{1, 2, 3, 4, 5}\n  EachInt(fn, i)\n\n  fmt.Printf(\"%#v\\n\", sum) //15\n```\n\nUsing a Typed Map\n``` go\n  var EachStringInt func(func(key string, value int), map[string]int)\n  var sum int\n\n  fn := func(v int, k string) {\n    sum += v\n  }\n\n  m := map[string]int{\"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4, \"e\": 5}\n  EachStringInt(fn, m)\n\n  fmt.Printf(\"%#v\\n\", sum) //15\n```\n\nOf note is the ability to close over variables within the calling scope.\n\n\n### \u003ca name=\"every\"\u003e\u003c/a\u003eEvery ###\n---------------------------------------------------------------------------\n\n\n\n\n### Map ###\n---------------------------------------------------------------------------\n\n``` go\nMap func([]A, func(A) B) []B\n```\n\nApplies the given function to each element of a slice, returning a slice of results\n\nThe base Map function accepts interface{} types and returns []interface{}\n\n``` go\n  // Map func(interface{}, func(interface{}) interface{}) []interface{}\n\n  s := []string{\"a\", \"b\", \"c\", \"d\"}\n\n  fn := func(s interface{}) interface{} {\n    return s.(string) + \"!\"\n  }\n\n  m := un.Map(ToI(s), fn)\n  fmt.Println(m) //[\"a!\", \"b!\", \"c!\", \"d!\"]\n```\n\nTyped Maps can be defined using a function type and the *MakeMap* helper.\n\n``` go\n  Map func([]A, func(A) B) []B\n\n  var SMap func([]string, func(string) string) []string\n  un.MakeMap(\u0026SMap)\n\n  m := un.SMap(s, fn)\n  fmt.Println(m) //[\"a!\", \"b!\", \"c!\", \"d!\"]\n```\n\nOf note is the return value of Map is a slice of the return type of the applied function.\n\n\n### Partition ###\n---------------------------------------------------------------------------\n\nPartition func([]A, func(A) bool) ([]A []A)\n\nPartition splits a slice or map based on the evaluation of the supplied function\n\nThe base Partition function accepts interface{} types and returns []interface{}\n\n\n``` go\n  // Partition func(interface{}, func(interface{}) bool) ([]interface{}, []interface{})\n\n  s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\n  fn := func(i interface{}) bool {\n    return (i.(int) % 2) == 1\n  }\n\n  odd, even := un.Partition(s, fn)\n\n  fmt.Println(odd)  //[1, 3, 5, 7, 9]\n  fmt.Println(even) //[2, 4, 6, 8, 10]\n```\n\nTyped Partitions can be defined using a function type and the *MakePartition* helper.\n\n``` go\n  // Partition func([]A, func(A) bool) ([]A []A)\n\n  var IPartition func([]int, func(int) bool) ([]int, []int)\n\n  un.MakePartition(\u0026IPartition)\n\n  s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}\n\n  fn := func(i int) bool {\n    return (i % 2) == 1\n  }\n\n  odd, even := un.IPartition(s, fn)\n\n  fmt.Println(odd)  //[1, 3, 5, 7, 9]\n  fmt.Println(even) //[2, 4, 6, 8, 10]\n```\n\n\nContains returns true if an object is in a slice.\n\n``` go\n  o := \"a\"\n  s := []string{\"a\", \"b\", \"c\"}\n\n  b := un.Contains(s, o)\n  fmt.Println(b) //true\n```\n\n\nToI converts a slice of arbitrary type []T into a slice of []interfaces{}\n\n``` go\n  s := []int{1, 1, 3, 5, 8, 13}\n  i := un.ToI(s)\n```\n\n\n\n\nNotes\n------------------------------------------\n\nI am aware that the whole idea is not particularly very TheGoWay™, but it is useful as a learning exercise, and it is useful for moving fast and optimising later.\n","funding_links":[],"categories":["Functional","Utilities","工具库","方法","函数式编程","实用工具","Relational Databases","Go"],"sub_categories":["Search and Analytic Databases","Advanced Console UIs","交流","检索及分析资料库","SQL 查询语句构建库","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobyhede%2Fgo-underscore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftobyhede%2Fgo-underscore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftobyhede%2Fgo-underscore/lists"}