{"id":13492618,"url":"https://github.com/wesovilabs/koazee","last_synced_at":"2025-09-09T15:38:32.693Z","repository":{"id":43039899,"uuid":"156842152","full_name":"wesovilabs/koazee","owner":"wesovilabs","description":"A StreamLike, Immutable, Lazy Loading and smart Golang Library to deal with slices.","archived":false,"fork":false,"pushed_at":"2020-11-18T17:04:42.000Z","size":4138,"stargazers_count":531,"open_issues_count":14,"forks_count":31,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-05-24T14:21:45.031Z","etag":null,"topics":["arrays","functional-programming","golang","golang-library","immutable","lazy-evaluation","slices"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wesovilabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-09T09:49:19.000Z","updated_at":"2025-05-22T21:27:38.000Z","dependencies_parsed_at":"2022-09-26T17:41:28.198Z","dependency_job_id":null,"html_url":"https://github.com/wesovilabs/koazee","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/wesovilabs/koazee","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fkoazee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fkoazee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fkoazee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fkoazee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wesovilabs","download_url":"https://codeload.github.com/wesovilabs/koazee/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wesovilabs%2Fkoazee/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274319046,"owners_count":25263197,"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","status":"online","status_checked_at":"2025-09-09T02:00:10.223Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["arrays","functional-programming","golang","golang-library","immutable","lazy-evaluation","slices"],"created_at":"2024-07-31T19:01:07.584Z","updated_at":"2025-09-09T15:38:32.637Z","avatar_url":"https://github.com/wesovilabs.png","language":"Go","funding_links":[],"categories":["Utilities","Go","工具库`可以提升效率的通用代码库和工具`","公用事业公司","工具库","Utility"],"sub_categories":["Utility/Miscellaneous","查询语","HTTP Clients","实用程序/Miscellaneous","Fail injection"],"readme":"[![Build Status](https://travis-ci.org/wesovilabs/koazee.svg?branch=master)](https://travis-ci.org/wesovilabs/koazee)\n[![Go Report Card](https://goreportcard.com/badge/github.com/wesovilabs/koazee)](https://goreportcard.com/report/github.com/wesovilabs/koazee)\n[![godoc](https://godoc.org/github.com/wesovilabs/koazee?status.svg)](http://godoc.org/github.com/wesovilabs/koazee)\n[![codecov](https://codecov.io/gh/wesovilabs/koazee/branch/master/graph/badge.svg)](https://codecov.io/gh/wesovilabs/koazee)\n[![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/avelino/awesome-go#Utilities)\n\n# Koazee\n\n\u003e Lazy like a koala, smart like a chimpanzee\n\n\n## What is Koazee?\n\nKoazee is a StreamLike, Immutable, Lazy Loading and smart Golang Library to deal with slices. \n\n\nVisit the [Koazee wiki](https://github.com/wesovilabs/koazee/wiki) to find out what Koazee can do.\n\n## Koazee Highlights\n\n- **Immutable**: Koazee won't modify your inputs. \n- **StreamLike**: We can combine operations up our convenience. \n- **Lazy loading**: Operations are not performed until they're required\n- **Generic**: Koazee provides a generic interface able to deal with slice of any type without creating custom functions.\n- **Focusing on performance**: First rule for implementing a new operation is providing the best possible performance.\n\n\n\n## Getting started\n\n### Installing\n\u003e Add Koazee to your project\n\n**Go modules**\n\n```\nmodule github.com/me/project\nrequire ( \n  github.com/wesovilabs/koazee vX.Y.Z\n)\n```\n\n**Glide**\n\n```\nglide get github.com/wesovilabs/koazee\n```\n\n**Go dep**\n\n```\ngo get github.com/wesovilabs/koazee\n```\n\n### Usage\n\n#### Stream creation\n\nLet's first obtain a stream from an existing array.\n\n```golang\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\nvar numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}\n\nfunc main() {\n\tfmt.Printf(\"slice: %v\\n\", numbers)\n\tstream := koazee.StreamOf(numbers)\n\tfmt.Printf(\"stream: %v\\n\", stream.Out().Val())\n}\n\n/**\ngo run main.go\n\nslice: [1 5 4 3 2 7 1 8 2 3]\nstream: [1 5 4 3 2 7 1 8 2 3]\n*/\n```\n\n#### Stream operations\n\nCurrent release v0.0.3 (Gibbon) brings us 20 generic operations that are showed below\n\n##### stream.At / stream.First / stream.Last\nThese operations return an element from the stream\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\nvar numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}\n\nfunc main() {\n\tstream := koazee.StreamOf(numbers)\n\tfmt.Printf(\"stream.At(4): %d\\n\", stream.At(4).Int())\n\tfmt.Printf(\"stream.First: %d\\n\", stream.First().Int())\n\tfmt.Printf(\"stream.Last: %d\\n\", stream.Last().Int())\n}\n\n/**\ngo run main.go\n\nstream.At(4): 2\nstream.First: 1\nstream.Last: 3\n*/\n```\n\n##### stream.Add / stream.Drop / stream.DropWhile / stream.DeleteAt / stream.Pop / stream.Set\nThese operations add or delete elements from the stream.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\nvar numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}\n\nfunc main() {\n\tfmt.Printf(\"input: %v\\n\", numbers)\n\n\tstream := koazee.StreamOf(numbers)\n\tfmt.Print(\"stream.Add(10): \")\n\tfmt.Println(stream.Add(10).Do().Out().Val())\n\n\tfmt.Print(\"stream.Drop(5): \")\n\tfmt.Println(stream.Drop(5).Do().Out().Val())\n\t\n\tfmt.Print(\"stream.DropWhile(val\u003c=5): \")\n\tfmt.Println(stream.DropWhile(func(element int)bool{return element\u003c=5}).Do().Out().Val())\n\n\tfmt.Print(\"stream.DeleteAt(4): \")\n\tfmt.Println(stream.DeleteAt(4).Do().Out().Val())\n\n\tfmt.Print(\"stream.Set(0,5): \")\n\tfmt.Println(stream.Set(0, 5).Do().Out().Val())\n\n\tfmt.Print(\"stream.Pop(): \")\n\tval, newStream := stream.Pop()\n\tfmt.Printf(\"%d ... \", val.Int())\n\tfmt.Println(newStream.Out().Val())\n\n}\n\n/**\ngo run main.go\n\ninput: [1 5 4 3 2 7 1 8 2 3]\nstream.Add(10): [1 5 4 3 2 7 1 8 2 3 10]\nstream.Drop(5): [1 4 3 2 7 1 8 2 3]\nstream.DropWhile(val\u003c=5): [7 8]\nstream.DeleteAt(4): [1 5 4 3 7 1 8 2 3]\nstream.Set(0,5): [5 5 4 3 2 7 1 8 2 3]\nstream.Pop(): 1 ... [5 4 3 2 7 1 8 2 3]\n*/\n```\n\n##### tream.Count / stream.IndexOf / stream.IndexesOf / stream.LastIndexOf / stream.Contains\nThese operations return info from the elements in the stream\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\nvar numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}\n\nfunc main() {\n\tfmt.Printf(\"input: %v\\n\", numbers)\n\tstream := koazee.StreamOf(numbers)\n\tcount, _ := stream.Count()\n\tfmt.Printf(\"stream.Count(): %d\\n\", count)\n\tindex, _ := stream.IndexOf(2)\n\tfmt.Printf(\"stream.IndexOf(2): %d\\n\", index)\n\tindexes, _ := stream.IndexesOf(2)\n    fmt.Printf(\"stream.IndexesOf(2): %d\\n\", indexes)\n\tindex, _ = stream.LastIndexOf(2)\n\tfmt.Printf(\"stream.LastIndexOf(2): %d\\n\", index)\n\tcontains, _ := stream.Contains(7)\n\tfmt.Printf(\"stream.Contains(7): %v\\n\", contains)\n}\n\n/**\ngo run main.go\n\ninput: [1 5 4 3 2 7 1 8 2 3]\nstream.Count(): 10\nstream.IndexOf(2): 4\nstream.IndexesOf(2): [4 8]\nstream.LastIndexOf(2): 8\nstream.Contains(7): true\n*/\n```\n\n##### stream.Sort / stream.Reverse\nThese operations organize the elements in the stream.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n\t\"strings\"\n)\n\nvar animals = []string{\"lynx\", \"dog\", \"cat\", \"monkey\", \"fox\", \"tiger\", \"lion\"}\n\nfunc main() {\n\tfmt.Print(\"input: \")\n\tfmt.Println(animals)\n\tstream := koazee.StreamOf(animals)\n\n\tfmt.Print(\"stream.Reverse(): \")\n\tfmt.Println(stream.Reverse().Out().Val())\n\n\tfmt.Print(\"stream.Sort(strings.Compare): \")\n\tfmt.Println(stream.Sort(strings.Compare).Out().Val())\n\n}\n\n/**\ngo run main.go\n\ninput: [lynx dog cat monkey fox tiger lion]\nstream.Reverse(): [lion tiger fox monkey cat dog lynx]\nstream.Sort(strings.Compare): [cat dog fox lion lynx monkey tiger]\n*/\n```\n\n##### stream.Take / stream.Filter / stream.RemoveDuplicates\nThese operations return a filtered stream.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\nvar animals = []string{\"lynx\", \"dog\", \"cat\", \"monkey\", \"dog\", \"fox\", \"tiger\", \"lion\"}\n\nfunc main() {\n\tfmt.Print(\"input: \")\n\tfmt.Println(animals)\n\tstream := koazee.StreamOf(animals)\n\n\tfmt.Print(\"stream.Take(1,4): \")\n\tfmt.Println(stream.Take(1, 4).Out().Val())\n\n\tfmt.Print(\"stream.Filter(len==4): \")\n\tfmt.Println(stream.\n\t\tFilter(\n\t\t\tfunc(val string) bool {\n\t\t\t\treturn len(val) == 4\n\t\t\t}).\n\t\tOut().Val(),\n\t)\n\tfmt.Print(\"stream.RemoveDuplicates(): \")\n\tfmt.Println(stream.RemoveDuplicates().Out().Val())\n}\n\n/**\ngo run main.go\n\ninput: [lynx dog cat monkey dog fox tiger lion]\nstream.Take(1,4): [dog cat monkey dog]\nstream.Filter(len==4): [lynx lion]\nstream.RemoveDuplicates(): [lynx dog cat monkey fox tiger lion]\n*/\n```\n##### stream.GroupBy\nThis operation creates groups depending on the returned function value\n\nYou can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in `stream.Out().Err().UserError()`.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n\t\"strings\"\n)\n\nvar animals = []string{\"lynx\", \"dog\", \"cat\", \"monkey\", \"dog\", \"fox\", \"tiger\", \"lion\"}\n\nfunc main() {\n\tfmt.Printf(\"input: %v\\n\", animals)\n\tstream := koazee.StreamOf(animals)\n\tfmt.Print(\"stream.GroupBy(strings.Len): \")\n\tout, _ := stream.GroupBy(func(val string)int{return len(val)})\n\tfmt.Println(out)\n}\n\n/**\ngo run main.go\n\ninput: [lynx dog cat monkey dog fox tiger lion]\nstream.GroupBy(strings.Len): map[5:[tiger] 4:[lynx lion] 3:[dog cat dog fox] 6:[monkey]]\n*/\n```\n\n\n##### stream.Map\nThis operation performs a modification over all the elements in the stream.\n\nYou can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in `stream.Out().Err().UserError()`.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n\t\"strings\"\n)\n\nvar animals = []string{\"lynx\", \"dog\", \"cat\", \"monkey\", \"dog\", \"fox\", \"tiger\", \"lion\"}\n\nfunc main() {\n\tfmt.Printf(\"input: %v\\n\", animals)\n\tstream := koazee.StreamOf(animals)\n\tfmt.Print(\"stream.Map(strings.Title): \")\n\tfmt.Println(stream.Map(strings.Title).Do().Out().Val())\n}\n\n/**\ngo run main.go\n\ninput: [lynx dog cat monkey dog fox tiger lion]\nstream.Map(strings.Title): [Lynx Dog Cat Monkey Dog Fox Tiger Lion]\n*/\n```\n\n##### stream.Reduce\nThis operation give us a single output after iterating over the elements in the stream.\n\nYou can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in `stream.Out().Err().UserError()`.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\nvar numbers = []int{1, 5, 4, 3, 2, 7, 1, 8, 2, 3}\n\nfunc main() {\n\tfmt.Printf(\"input: %v\\n\", numbers)\n\tstream := koazee.StreamOf(numbers)\n\tfmt.Print(\"stream.Reduce(sum): \")\n\tfmt.Println(stream.Reduce(func(acc, val int) int {\n\t\treturn acc + val\n\t}).Int())\n}\n\n/**\ngo run main.go\n\ninput: [1 5 4 3 2 7 1 8 2 3]\nstream.Reduce(sum): 36\n*/\n```\n\n##### stream.ForEach\nThis operation iterates over the element in the stream.\n\nYou can now optionally return an error as the second parameter to stop processing of the stream. The error will be available in `stream.Out().Err().UserError()`.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n)\n\ntype message struct {\n\tuser    string\n\tmessage string\n}\n\nvar messages = []*message{\n\t{user: \"John\", message: \"Hello Jane\"},\n\t{user: \"Jane\", message: \"Hey John, how are you?\"},\n\t{user: \"John\", message: \"I'm fine! and you?\"},\n\t{user: \"Jane\", message: \"Me too\"},\n}\n\nfunc main() {\n\n\tstream := koazee.StreamOf(messages)\n\tstream.ForEach(func(m *message) {\n\t\tfmt.Printf(\"%s: \\\"%s\\\"\\n\", m.user, m.message)\n\t}).Do()\n}\n\n/**\ngo run main.go\n\nJohn: \"Hello Jane\"\nJane: \"Hey John, how are you?\"\nJohn: \"I'm fine! and you?\"\nJane: \"Me too\"\n*/\n```\n\n#### Combine operations and evaluate them lazily\nThe main goal of Koazee is providing a set of operations that can be combined and being evaluated lazily.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/wesovilabs/koazee\"\n\t\"strings\"\n)\n\ntype Person struct {\n\tName string\n\tMale bool\n\tAge  int\n}\n\nvar people = []*Person{\n\t{\"John Smith\", true, 32},\n\t{\"Peter Pan\", true, 17},\n\t{\"Jane Doe\", false, 20},\n\t{\"Anna Wallace\", false, 35},\n\t{\"Tim O'Brian\", true, 13},\n\t{\"Celia Hills\", false, 15},\n}\n\nfunc main() {\n\tstream := koazee.\n\t\tStreamOf(people).\n\t\tFilter(func(person *Person) bool {\n\t\t\treturn !person.Male\n\t\t}).\n\t\tSort(func(person, otherPerson *Person) int {\n\t\t\treturn strings.Compare(person.Name, otherPerson.Name)\n\t\t}).\n\t\tForEach(func(person *Person) {\n\t\t\tfmt.Printf(\"%s is %d years old\\n\", person.Name, person.Age)\n\t\t})\n\n\tfmt.Println(\"Operations are not evaluated until we perform stream.Do()\\n\")\n\tstream.Do()\n}\n\n/**\ngo run main.go\n\nOperations are not evaluated until we perform stream.Do()\n\nAnna Wallace is 35 years old\nCelia Hills is 15 years old\nJane Doe is 20 years old\n */\n```\n\n## Available Operations\n\n| Operation  | Description  | Since  |\n|---|---|---|\n| Add | It adds a new element in the last position |  v0.0.1 |\n| At | It returns the element in the given position |  v0.0.1 |\n| Contains | It checks if the given element is found in the stream.|  v0.0.1 |\n| Count | It returns the number of elements in a stream|  v0.0.1 |\n| DeleteAt| It remove the elements in the given position |  v0.0.3 |\n| Drop | It removes an element from the stream |  v0.0.1 |\n| DropWhile | It removes the elements in the stream that match with the given input function | v0.0.4 |\n| Filter | It discards those elements that doesn't match with the provided filter|  v0.0.1 |\n| First | It returns the element in the first position |  v0.0.1 |\n| ForEach | It does something over all the elements in the stream.|  v0.0.1 |\n| GroupBy | It creates groups depending on the returned function value|  v0.0.4 |\n| IndexOf | It returns the first index of the  element in the stream.|  v0.0.3 |\n| IndexesOf | It returns the index for all the occurrences of the  element in the stream.|  v0.0.4 |\n| Last | It returns the element in the last position |  v0.0.1 |\n| LastIndexOf | It returns the last occurrence for the  element in the stream.|  v0.0.3 |\n| Map | It converts the element in the stream |  v0.0.1 |\n| Pop | It extracts the first element in the stream and return this and the new stream | v0.0.3 |\n| Reduce | It reduceshe stream to a single value by executing a provided function for each value of the stream|  v0.0.1 |\n| RemoveDuplicates | It removes duplicated elements.|  v0.0.1 |\n| Reverse| It reverses the sequence of elements in the stream.| v0.0.3 |\n| Set | It replaces the element in the given index by the provided value |  v0.0.3 |\n| Sort | It sorts the elements in the stream|  v0.0.1 |\n| Take | It returns a stream with the elements between the given indexes |  v0.0.3 |\n\n## Samples\n\nA rich and growing set of examples can be found on [koazee-samples](https://github.com/wesovilabs/koazee-samples)\n\n## Benchmark\n\nYou can check the Benchmark for the Koazee operations [here](https://github.com/wesovilabs/koazee/wiki/Benchmark-Report)\n\nA benchmark comparison with other frameworks can be found in [Koazee vs Go-Funk vs Go-Linq](https://medium.com/@ivan.corrales.solera/koazee-vs-go-funk-vs-go-linq-caf8ef18584e)\n\n## Guides \u0026 Tutorials\n\n[Shopping cart with Koazee](https://medium.com/wesovilabs/koazee-the-shopping-cart-a381bba32955)\n\n\n## Roadmap\n\nThis is only the beginning! By the way, If you missed any operation in Koazee v0.0.3,  or you found a bug, please [create a new issue on Github or vote the existing ones](https://github.com/wesovilabs/koazee/issues)!\n\n\n## Contributors\n- [@ivancorrales](https://github.com/ivancorrales)\n- [@xuyz](https://github.com/xuyz)\n- [@u5surf](https://github.com/u5surf)\n- [@flowonyx](https://github.com/flowonyx)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesovilabs%2Fkoazee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwesovilabs%2Fkoazee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwesovilabs%2Fkoazee/lists"}