{"id":13743547,"url":"https://github.com/chen3feng/stl4go","last_synced_at":"2025-04-05T04:12:55.172Z","repository":{"id":49318084,"uuid":"517278683","full_name":"chen3feng/stl4go","owner":"chen3feng","description":"Generic Container and Algorithm Library for Go","archived":false,"fork":false,"pushed_at":"2024-07-30T06:20:20.000Z","size":272,"stargazers_count":331,"open_issues_count":16,"forks_count":51,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-29T03:07:08.123Z","etag":null,"topics":["go","golang","stl"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chen3feng.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-24T09:23:37.000Z","updated_at":"2025-03-19T11:32:32.000Z","dependencies_parsed_at":"2024-01-17T12:19:10.044Z","dependency_job_id":"bd80f800-5b8b-4c46-85dc-05fc71280f40","html_url":"https://github.com/chen3feng/stl4go","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chen3feng%2Fstl4go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chen3feng%2Fstl4go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chen3feng%2Fstl4go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chen3feng%2Fstl4go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chen3feng","download_url":"https://codeload.github.com/chen3feng/stl4go/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284951,"owners_count":20913704,"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":["go","golang","stl"],"created_at":"2024-08-03T05:00:50.645Z","updated_at":"2025-04-05T04:12:55.148Z","avatar_url":"https://github.com/chen3feng.png","language":"Go","funding_links":[],"categories":["Golang"],"sub_categories":["Container"],"readme":"# stl4go -- STL for Golang\n\nEnglish | [简体中文](README_zh.md)\n\nThis library contains generic containers and algorithms, it is designed to be STL for Golang.\n\n[![License Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-red.svg)](COPYING)\n[![Golang](https://img.shields.io/badge/Language-go1.18+-blue.svg)](https://go.dev/)\n![Build Status](https://github.com/chen3feng/stl4go/actions/workflows/go.yml/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/chen3feng/stl4go/badge.svg?branch=master)](https://coveralls.io/github/chen3feng/stl4go?branch=master)\n[![GoReport](https://goreportcard.com/badge/github.com/securego/gosec)](https://goreportcard.com/report/github.com/chen3feng/stl4go)\n[![Go Reference](https://pkg.go.dev/badge/github.com/chen3feng/stl4go.svg)](https://pkg.go.dev/github.com/chen3feng/stl4go)\n\nThis library depends on go generics, which is introduced in 1.18+.\n\n\u003c!-- gomarkdoc:embed:start --\u003e\n\n\u003c!-- Code generated by gomarkdoc. DO NOT EDIT --\u003e\n\n```go\nimport \"github.com/chen3feng/stl4go\"\n```\n\nPackage stl4go is a generic container and algorithm library for go.\n\n## Introduce\n\nThis library is a general container and algorithm library that attempts to learn from the C++ STL implementation after Go 1.18 began to support generics.\n(Personally I's totally unacceptable for me  use to languages without generics, so I didn't try it until go 1.18).\n\nThe code quality of this library is quite high and follows the latest best practices in the industry.\nTest coverage is close💯%, ✅，CI, and [gosec](https://securego.io/) check are both set up, got\n[![GoReport](https://goreportcard.com/badge/github.com/securego/gosec)](https://goreportcard.com/report/github.com/chen3feng/stl4go) score。\n\n## Features\n\nAs we all know, C++'s STL includes containers, algorithms, and iterators relate the two.\n\nDue to language limitations, it is impossible and unnecessary to completely imitate the interface of C++ STL in Go,\nso C++ users may feel familiar, and sometimes (maybe) feel more convenient.\n\n### Containers\n\nThere are following container interfaces:\n\n- `Container` is the base interface for all containers\n- `Map` is a key-value associative container\n- `Set` is set container\n- `SortedMap` is a ordered key-value associative container\n- `SortedSet` is a ordered set container\n- `Queue` is a FIFO Queue\n- `Deque` is a double ended queue\n\nDifferent interface has different methods. The `Container` interface has following methods:\n\n- `IsEmpty() bool` returns whether the container is empty\n- `Len() int` returns the number of elements in the container\n- `Clear()` to clear the container\n\nRead [source code](container.go) for details.\n\nCurrently container implementations are:\n\n- [x] `BuiltinSet` provided a set funtionality based on Go's own `map`. It provides basic operations such as insert,\n      search and remove, as well as advanced functions such as union, intersection, difference, subset, superset, and disjoint.\n- [x] `Vector` is a thin encapsulation based on `slice`. It provides functions such as insertion and deletion in the middle, range deletion, etc.,\n      and is still compatible with slices.\n- [x] `DList` is a doubly linked list, supports push/popup at both ending.\n- [x] `SList` is a singly linked list, supports push/popup at the head and push at the tail.\n- [x] [SkipList](skiplist.md) is an ordered associative container that fills the gap where Go `map` only supports unordered.\n      This is currently the fastest skip list I tested in GitHub, see [skiplist-survey](https://github.com/chen3feng/skiplist-survey) for performance comparison\n- [x] `SkipList` is a `SortedSet` container based on the skiplist.\n- [x] `Stack`, is a FILO container based on Slice implementation\n- [x] `DListQueue` is a bidirectional FIFO queue, implemented based on linked list.\n- [x] `PriorityQuque` is a priority queue based on heap. Much easier to use and faster than [container/heap](https://pkg.go.dev/container/heap).\n\n### Non-Container Components\n\n- [x] `Pool` A type safe Pool, is implemented based on `sync.Pool`.\n\n### Iterators\n\nVector, DList and SkipList support iterators.\n\n```go\n// Iterator is the interface for container's iterator.\ntype Iterator[T any] interface {\n\tIsNotEnd() bool // Whether it is point to the end of the range.\n\tMoveToNext()    // Let it point to the next element.\n\tValue() T       // Return the value of current element.\n}\n\n// MutableIterator is the interface for container's mutable iterator.\ntype MutableIterator[T any] interface {\n\tIterator[T]\n\tPointer() *T // Return the pointer to the value of current element.\n}\n```\n\n```go\nl := stl4go.NewDListOf(Range(1, 10000)...)\nsum := 0\nfor i := 0; i \u003c b.N; i++ {\n    for it := l.Iterate(); it.IsNotEnd(); it.MoveToNext() {\n        sum += it.Value()\n    }\n}\n```\n\nThe iterator of SkipList is `MutableMapIterator`:\n\n```go\n// MapIterator is the interface for map's iterator.\ntype MapIterator[K any, V any] interface {\n\tIterator[V]\n\tKey() K // The key of the element\n}\n\n// MutableMapIterator is the interface for map's mutable iterator.\ntype MutableMapIterator[K any, V any] interface {\n\tMutableIterator[V]\n\tKey() K // The key of the element\n}\n```\n\nSkipList also supports range iteration:\n\n```go\nsl := stl4go.NewSkipList[int, int]()\nfor i := 0; i \u003c 1000; i++ {\n    sl.Insert(i, 0)\n}\nit := sl.FindRange(120, 350)\n```\n\nIterating over `it` only yields the keys between 120 and 349.\n\nIn many cases, it is more convenient to use the `ForEach` and `ForEachIf` methods provided by the container,\nand the performance is often better:\n\n```go\nfunc TestSkipList_ForEach(t *testing.T) {\n    sl := newSkipListN(100)\n    a := []int{}\n    sl.ForEach(func(k int, v int) {\n        a = append(a, k)\n    })\n    expectEq(t, len(a), 100)\n    expectTrue(t, IsSorted(a))\n}\n```\n\n`ForEachIf` is used for scenarios that you want to end early during the iteration:\n\n ```go\nfunc Test_DList_ForEachIf(t *testing.T) {\n    l := NewDListOf(1, 2, 3)\n    c := 0\n    l.ForEachIf(func(n int) bool {\n        c = n\n        return n != 2\n    })\n    expectEq(t, c, 2)\n}\n ```\n\nYou can use `ForEachMutable` or `ForEachMutable` to modify the value of an element during the iteration:\n\n```go\nfunc TestSkipList_ForEachMutable(t *testing.T) {\n    sl := newSkipListN(100)\n    sl.ForEachMutable(func(k int, v *int) {\n        *v = -*v\n    })\n    for i := 0; i \u003c sl.Len(); i++ {\n        expectEq(t, *sl.Find(i), -i)\n    }\n}\n```\n\n### Algorithms\n\nDue to the limitations of language, most algorithms only support Slice.\nThe functions name of the algorithms ends with `If` or `Func`,\nindicating that a custom comparison function can be passed.\n\n#### Generate\n\n- `Range` returns a Slice of contains integers in the range of `[begin, end)`\n- `Generate` generates a sequence with the given function to fill the Slice\n\n#### Data manipulation\n\n- `Copy` return a copies of specified slice\n- `CopyTo` copies all elements in slice a to slice to, return the copied slice.\n- `Fill` repeatedly fills a slice with the specified value\n- `FillZero` fills each element in slice a with zero value.\n- `FillPattern` repeatedly fills a slice with the specified pattern\n- `Replace` replaces every element that equals to old with new\n- `ReplaceIf` replaces every element that make preq returns true with new\n- `Transform` passes the value at each position of the slice to the specified function and sets it back with its return value\n- `TransformTo` passes the value at each position of slice `a` to the specified function,\n  sets its return value to the corresponding position in slice `b`, and returns a slice of corresponding length of slice `b`\n- `TransformCopy` passes the value at each position of the slice to the specified function,\n  sets its return value to the corresponding position in a new slice and returns\n- `Unique` removes adjacent duplicate elements from a slice and returns a slice with new length containing the remaining elements,\n  `UniqueCopy` returns a copy without modifying the original slice\n- `Remove` removes all elements in the slice equal to the specified value, `RemoveCopy` returns a copy without modifying the original slice\n- `RemoveIf` removes all elements in the slice that are equivalent to making the specified function return `true`,\n  `RemoveIfCopy` does not modify the original slice but returns a copy\n- `Shuffle` random shuffle elements in the slice\n- `Reverse` reverses a slice, `ReverseCopy` returns a copy without modifying the original slice\n\n#### Compute\n\n- `Sum` Sum\n- `SumAs` sums and returns a result as another type (eg. use `int64` to return the sum of `[]int32`).\n- `Average` finds the average value.\n- `AverageAs` averages and returns the result as another type (eg. use `float64` to return the sum of `[]int`).\n- `Count` returns the number equivalent to the specified value\n- `CountIf` returns the number of elements for which the specified function returns `true`\n\n#### Compare\n\n- `Equal` checks whether two sequences are equal\n- `Compare` compares two sequences and returns `-1`, `0`, and `1` in lexicographical order, respectively indicating the relationship of 2 slices.\n\n#### Lookup\n\n- `Min`, `Max` find the maximum and minimum\n- `MinN`, `MaxN`, `MinMax` return the maximum and minimum values in the slice\n- `Find` linearly finds the first specified value and returns its index\n- `FindIf` linearly finds the first value that make specified function returns `true` and returns its index\n- `AllOf`, `AnyOf`, `NoneOf` return whether all, any, or none of the elements in the range can make the passed function return `true` accordingly.\n\n#### Binary Search\n\nSee C++ STL.\n\n- `BinarySearch`\n- `LowerBound`\n- `UpperBound`\n\n#### Sort\n\n- `Sort` sorting\n- `DescSort` descending sorting\n- `StableSort` stable sorting\n- `DescStableSort` descending stable sorting\n- `IsSorted` check whether the slice is sorted\n- `IsDescSorted` check whether the slice is sorted in descending order\n\n#### heap\n\n[Heap](heap.md) provides basic min heap algorithms:\n\n- `MakeMinHeap` Convert a slice to a min heap\n- `IsMinHeap` Check whether a slice is a min heap\n- `PushMinHeap` Pushes an element in to the heap\n- `PopMinHeap` Popups an element from the top of the heap\n- `RemoveMinHeap` Removes an element at index from the heap\n\nand variants with custome comparasion function:\n\n- `MakeHeapFunc`\n- `IsHeapFunc`\n- `PushHeapFunc`\n- `PopHeapFunc`\n- `RemoveHeapFunc`\n\nboth of them are mush faster and easier to use than [container/heap](https://pkg.go.dev/container/heap).\n\nSee detailed usage and benchmark report in the [document of heap](heap.md)。\n\n### Interface Design and Naming\n\nThe design leart much from the C++ STL. The `T` here represents `template`. Yes, Go's generic is not template. but who made C++ so influential and STL so famous?\n\nMany libraries are designed for small code repositories or split into multiple subpackages in one repository.\nFor example:\n\n```go\nimport (\n    \"github.com/someone/awesomelib/skiplist\"\n    \"github.com/someone/awesomelib/binarysearch\"\n)\n\nfunc main() {\n    sl := skiplist.New()\n}\n```\n\nThis way of writing seems elegant, but because everyone likes good names, import renaming has to be introduced in use in case of package name conflict,\nand different users have different renaming style, which increases the mental burden of code reading and writing.\n\nI don't like this style, especially in a larger repository.\n\nTherefore, this library is all under the `stl4go` package, and it is expected that it will not namesake in other people's libraries.\n\n### TODO\n\nSee [Issue](https://github.com/chen3feng/stl4go/issues)。\n\nAnd add more detailed documents.\n\n## Go Doc\n\nClick to view the [generated doc](generated_doc.md).\n\n## Reference\n\n- [C++ STL](https://en.wikipedia.org/wiki/Standard_Template_Library)\n- [liyue201/gostl](https://github.com/liyue201/gostl)\n- [zyedidia/generic](https://github.com/zyedidia/generic)\n- [hlccd/goSTL](https://github.com/hlccd/goSTL)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchen3feng%2Fstl4go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchen3feng%2Fstl4go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchen3feng%2Fstl4go/lists"}