{"id":28729772,"url":"https://github.com/didi/collection","last_synced_at":"2025-06-15T17:11:01.440Z","repository":{"id":57488691,"uuid":"185746486","full_name":"didi/collection","owner":"didi","description":"go collection package for fasting coding","archived":false,"fork":false,"pushed_at":"2020-10-09T02:28:11.000Z","size":44,"stargazers_count":127,"open_issues_count":0,"forks_count":23,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-06-20T05:06:42.369Z","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":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/didi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-09T07:15:28.000Z","updated_at":"2024-06-20T05:06:42.369Z","dependencies_parsed_at":"2022-08-29T13:32:03.716Z","dependency_job_id":null,"html_url":"https://github.com/didi/collection","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/didi/collection","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didi%2Fcollection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didi%2Fcollection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didi%2Fcollection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didi%2Fcollection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/didi","download_url":"https://codeload.github.com/didi/collection/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/didi%2Fcollection/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260016055,"owners_count":22946321,"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":"2025-06-15T17:11:00.627Z","updated_at":"2025-06-15T17:11:01.417Z","avatar_url":"https://github.com/didi.png","language":"Go","funding_links":["https://opencollective.com/collection"],"categories":[],"sub_categories":[],"readme":"# collection\n\nCollection包目标是用于替换golang原生的Slice，使用场景是在大量不追求极致性能，追求业务开发效能的场景。\n\n| 版本 | 说明 |\n| ------| ------ |\n| 1.2.0 |  增加对象指针数组，增加测试覆盖率, 增加ToInterfaces方法 |\n| 1.1.2 |  增加一些空数组的判断，解决一些issue |\n| 1.1.1 |  对collection包进行了json解析和反解析的支持，对mix类型支持了SetField和RemoveFields的类型设置 |\n| 1.1.0 |  增加了对int32的支持，增加了延迟加载，增加了Copy函数，增加了compare从ICollection传递到IMix，使用快排加速了Sort方法 |\n| 1.0.1 |  第一次发布 |\n\n`go get github.com/jianfengye/collection`\n\n创建collection库的说明文章见：[一个让业务开发效率提高10倍的golang库](https://www.cnblogs.com/yjf512/p/10818089.html)\n\nCollection包目前支持的元素类型：int32, int, int64, float32, float64, string, struct。\n\n\n\n使用下列几个方法进行初始化Collection:\n\n```go\nNewIntCollection(objs []int) *IntCollection\n\nNewInt64Collection(objs []int64) *Int64Collection\n\nNewInt32Collection(objs []int32) *Int32Collection\n\nNewFloat64Collection(objs []float64) *Float64Collection\n\nNewFloat32Collection(objs []float32) *Float32Collection\n\nNewStrCollection(objs []string) *StrCollection\n\nNewObjCollection(objs interface{}) *ObjCollection\n\nNewObjPointCollection(objs interface{}) *ObjPointCollection\n```\n\nCollection的Error是随着Collection对象走，或者下沉到IMix中，所以可以放心在ICollection和IMix进行链式调用，只需要最后进行一次错误检查即可。\n\n```\nret, err := objColl.Map(func(item interface{}, key int) IMix {\n    foo := item.(Foo)\n    return NewMix(foo.A)\n}).Reduce(func(carry IMix, item IMix) IMix {\n    ret, _ := carry.ToString()\n    join, _ := item.ToString()\n    return NewMix(ret + join)\n}).ToString()\nif err != nil {\n    ...\n}\n```\n\n支持的方法有:\n\n[Append](#Append) 挂载一个元素到当前Collection\n\n[Avg](#Avg) 返回Collection的数值平均数，只能数值类型coll调用\n\n[Contain](#Contain) 判断一个元素是否在Collection中。非数值类型必须设置对象compare方法。\n\n[Copy](#Copy) 根据当前的数组，创造出一个同类型的数组\n\n[DD](#DD) 按照友好的格式展示Collection\n\n[Diff](#Diff) 获取前一个Collection不在后一个Collection中的元素, 只能数值类型Diff调用\n\n[Each](#Each) 对Collection中的每个函数都进行一次函数调用\n\n[Every](#Every) 判断Collection中的每个元素是否都符合某个条件\n\n[ForPage](#ForPage) 将Collection函数进行分页\n\n[Filter](#Filter) 根据过滤函数获取Collection过滤后的元素\n\n[First](#First) 获取符合过滤条件的第一个元素\n\n[Index](#Index) 获取元素中的第几个元素，下标从0开始\n\n[IsEmpty](#IsEmpty) 判断一个Collection是否为空\n\n[IsNotEmpty](#IsNotEmpty) 判断一个Collection是否为空\n\n[Join](#Join) 将Collection中的元素按照某种方式聚合成字符串\n\n[Last](#Last) 获取该Collection中满足过滤的最后一个元素\n\n[Merge](#Merge) 将两个Collection的元素进行合并\n\n[Map](#Map) 对Collection中的每个函数都进行一次函数调用\n\n[Mode](#Mode) 获取Collection中的众数\n\n[Max](#Max) 获取Collection中的最大元素\n\n[Min](#Min) 获取Collection中的最小元素\n\n[Median](#Median) 获取Collection的中位数\n\n[NewEmpty](#NewEmpty) 根据当前的数组，创造出一个同类型的数组\n\n[Nth](#Nth) 获取从offset偏移量开始的每第n个\n\n[Pad](#Pad) 填充Collection数组\n\n[Pop](#Pop) 从Collection右侧弹出一个元素\n\n[Push](#Push) 往Collection的右侧推入一个元素\n\n[Prepend](#Prepend) 往Collection左侧加入元素\n\n[Pluck](#Pluck) 将对象数组中的某个元素提取出来组成一个新的Collection\n\n[Reject](#Reject) 将满足过滤条件的元素删除\n\n[Reduce](#Reduce) 对Collection中的所有元素进行聚合计算\n\n[Random](#Random) 随机获取Collection中的元素\n\n[Reverse](#Reverse) 将Collection数组进行转置\n\n[Slice](#Slice) 获取Collection中的片段\n\n[Search](#Search) 查找Collection中第一个匹配查询元素的下标\n\n[Sort](#Sort) 将Collection中的元素进行升序排列输出\n\n[SortDesc](#SortDesc) 将Collection中的元素按照降序排列输出\n\n[Sum](#Sum) 返回Collection中的元素的和\n\n[Shuffle](#Shuffle) 将Collection中的元素进行乱序排列\n\n[SortBy](#SortBy) 根据对象数组中的某个元素进行Collection升序排列\n\n[SortByDesc](#SortByDesc) 根据对象数组中的某个元素进行Collection降序排列\n\n[ToInts](#ToInts) 将Collection变化为int数组\n\n[ToInt64s](#ToInt64s) 将Collection变化为int64数组\n\n[ToFloat64s](#ToFloat64s) 将Collection变化为float64数组\n\n[ToFloat32s](#ToFloat32s) 将Collection变化为float32数组\n\n[ToMixs](#ToMixs) 将Collection变化为Mix数组\n\n[ToInterfaces](#ToInterfaces) 将collection变化为interface{}数组\n\n[Unique](#Unique) 将Collection中重复的元素进行合并\n\n### Append\n\n`Append(item interface{}) ICollection`\n\nAppend挂载一个元素到当前Collection，如果挂载的元素类型不一致，则会在Collection中产生Error\n\n```\nintColl := NewIntCollection([]int{1,2})\nintColl.Append(3)\nif intColl.Err() == nil {\n    intColl.DD()\n}\n\n/*\nIntCollection(3):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n}\n*/\n```\n\n### Avg\n\n`Avg() IMix`\n\n返回Collection的数值平均数，这里会进行类型降级，int,int64,float64的数值平均数都是返回float64类型。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nmode, err := intColl.Avg().ToFloat64()\nif err != nil {\n    t.Fatal(err.Error())\n}\nif mode != 2.0 {\n    t.Fatal(\"Avg error\")\n}\n```\n\n### Copy\n\nCopy方法根据当前的数组，创造出一个同类型的数组，有相同的元素\n\n```\nfunc TestAbsCollection_Copy(t *testing.T) {\n\tintColl := NewIntCollection([]int{1, 2})\n\tintColl2 := intColl.Copy()\n\tintColl2.DD()\n\tif intColl2.Count() != 2 {\n\t\tt.Fatal(\"Copy失败\")\n\t}\n\tif reflect.TypeOf(intColl2) != reflect.TypeOf(intColl) {\n\t\tt.Fatal(\"Copy类型失败\")\n\t}\n}\n```\n\n\n\n### Contain\n\n`Contains(obj interface{}) bool`\n\n判断一个元素是否在Collection中，必须设置compare函数\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nif intColl.Contains(1) != true {\n    t.Fatal(\"contain 错误1\")\n}\nif intColl.Contains(5) != false {\n    t.Fatal(\"contain 错误2\")\n}\n```\n\n### Diff\n\n`Diff(arr ICollection) ICollection`\n\n获取前一个Collection不在后一个Collection中的元素，必须设置compare函数\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nintColl2 := NewIntCollection([]int{2, 3, 4})\n\ndiff := intColl.Diff(intColl2)\ndiff.DD()\nif diff.Count() != 1 {\n    t.Fatal(\"diff 错误\")\n}\n\n/*\nIntCollection(1):{\n\t0:\t1\n}\n*/\n```\n\n### DD \n\n`DD()`\n\nDD方法按照友好的格式展示Collection\n\n```\na1 := Foo{A: \"a1\"}\na2 := Foo{A: \"a2\"}\n\nobjColl := NewObjCollection([]Foo{a1, a2})\nobjColl.DD()\n\n/*\nObjCollection(2)(collection.Foo):{\n\t0:\t{A:a1}\n\t1:\t{A:a2}\n}\n*/\n\nintColl := NewIntCollection([]int{1,2})\nintColl.DD()\n\n/*\nIntCollection(2):{\n\t0:\t1\n\t1:\t2\n}\n*/\n```\n\n\n### Each\n\n`Each(func(item interface{}, key int))`\n\n对Collection中的每个函数都进行一次函数调用。传入的参数是回调函数。\n\n如果希望在某次调用的时候中止，在此次调用的时候设置Collection的Error，就可以中止调用。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4})\nsum := 0\nintColl.Each(func(item interface{}, key int) {\n    v := item.(int)\n    sum = sum + v\n})\n\nif intColl.Err() != nil {\n    t.Fatal(intColl.Err())\n}\n\nif sum != 10 {\n    t.Fatal(\"Each 错误\")\n}\n\nsum = 0\nintColl.Each(func(item interface{}, key int) {\n    v := item.(int)\n    sum = sum + v\n    if sum \u003e 4 {\n        intColl.SetErr(errors.New(\"stop the cycle\"))\n        return\n    }\n})\n\nif sum != 6 {\n    t.Fatal(\"Each 错误\")\n}\n\n/*\nPASS\n*/\n```\n\n### Every\n\n`Every(func(item interface{}, key int) bool) bool`\n\n判断Collection中的每个元素是否都符合某个条件，只有当每个元素都符合条件，才整体返回true，否则返回false。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4})\nif intColl.Every(func(item interface{}, key int) bool {\n    i := item.(int)\n    return i \u003e 1\n}) != false {\n    t.Fatal(\"Every错误\")\n}\n\nif intColl.Every(func(item interface{}, key int) bool {\n    i := item.(int)\n    return i \u003e 0\n}) != true {\n    t.Fatal(\"Every错误\")\n}\n```\n\n### ForPage\n\n`ForPage(page int, perPage int) ICollection`\n\n将Collection函数进行分页，按照每页第二个参数的个数，获取第一个参数的页数数据。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\nret := intColl.ForPage(1, 2)\nret.DD()\n\nif ret.Count() != 2 {\n    t.Fatal(\"For page错误\")\n}\n\n/*\nIntCollection(2):{\n\t0:\t3\n\t1:\t4\n}\n*/\n```\n\n\n### Filter\n\n`Filter(func(item interface{}, key int) bool) ICollection`\n\n根据过滤函数获取Collection过滤后的元素。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nintColl.Filter(func(obj interface{}, index int) bool {\n    val := obj.(int)\n    if val == 2 {\n        return true\n    }\n    return false\n}).DD()\n\n/*\nIntCollection(2):{\n\t0:\t2\n\t1:\t2\n}\n*/\n```\n\n### First\n\n`First(...func(item interface{}, key int) bool) IMix`\n\n获取符合过滤条件的第一个元素，如果没有填写过滤函数，返回第一个元素。\n\n注：只能传递0个或者1个过滤函数，如果传递超过1个过滤函数，只有第一个过滤函数起作用\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nintColl.First(func(obj interface{}, index int) bool {\n    val := obj.(int)\n    if val \u003e 2 {\n        return true\n    }\n    return false\n}).DD()\n\n/*\nIMix(int): 3 \n*/\n\n```\n\n```\nfunc TestIntCollection_Filter(t *testing.T) {\n\tintColl := NewIntCollection([]int{1,2,3})\n\ta, err := intColl.First().ToInt()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif !reflect.DeepEqual(a, 1) {\n\t\tt.Fatal(\"filter error\")\n\t}\n}\n```\n\n### Index\n\n`Index(i int) IMix`\n\nIndex获取元素中的第几个元素，下标从0开始，如果i超出了长度，则Collection记录错误。\n\n```\nintColl := NewIntCollection([]int{1,2})\nfoo := intColl.Index(1)\nfoo.DD()\n\n/*\nIMix(int): 2 \n*/\n```\n\n### IsEmpty\n\n`IsEmpty() bool`\n\n判断一个Collection是否为空，为空返回true, 否则返回false\n\n```go\nintColl := NewIntCollection([]int{1,2})\nprintln(intColl.IsEmpty())  // false\n```\n\n### IsNotEmpty\n\n`IsNotEmpty() bool`\n\n判断一个Collection是否为空，为空返回false，否则返回true\n```go\nintColl := NewIntCollection([]int{1,2})\nprintln(intColl.IsNotEmpty()) // true\n```\n\n\n### Join\n\n`Join(split string, format ...func(item interface{}) string) string`\n\n将Collection中的元素按照某种方式聚合成字符串。该函数接受一个或者两个参数，第一个参数是聚合字符串的分隔符号，第二个参数是聚合时候每个元素的格式化函数，如果没有设置第二个参数，则使用`fmt.Sprintf(\"%v\")`来该格式化\n\n```go\nintColl := NewIntCollection([]int{2, 4, 3})\nout := intColl.Join(\",\")\nif out != \"2,4,3\" {\n    t.Fatal(\"join错误\")\n}\nout = intColl.Join(\",\", func(item interface{}) string {\n    return fmt.Sprintf(\"'%d'\", item.(int))\n})\nif out != \"'2','4','3'\" {\n    t.Fatal(\"join 错误\")\n}\n```\n\n### Last\n\n`Last(...func(item interface{}, key int) bool) IMix`\n\n获取该Collection中满足过滤的最后一个元素，如果没有填写过滤条件，默认返回最后一个元素\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 3, 2})\nlast, err := intColl.Last().ToInt()\nif err != nil {\n    t.Fatal(\"last get error\")\n}\nif last != 2 {\n    t.Fatal(\"last 获取错误\")\n}\n\nlast, err = intColl.Last(func(item interface{}, key int) bool {\n    i := item.(int)\n    return i \u003e 2\n}).ToInt()\n\nif err != nil {\n    t.Fatal(\"last get error\")\n}\nif last != 3 {\n    t.Fatal(\"last 获取错误\")\n}\n```\n\n\n### Merge\n\n`Merge(arr ICollection) ICollection`\n\n将两个Collection的元素进行合并，这个函数会修改原Collection。\n\n```go\nintColl := NewIntCollection([]int{1, 2 })\n\nintColl2 := NewIntCollection([]int{3, 4})\n\nintColl.Merge(intColl2)\n\nif intColl.Err() != nil {\n    t.Fatal(intColl.Err())\n}\n\nif intColl.Count() != 4 {\n    t.Fatal(\"Merge 错误\")\n}\n\nintColl.DD()\n\n/*\nIntCollection(4):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n\t3:\t4\n}\n*/\n```\n\n### Map\n\n`Map(func(item interface{}, key int) interface{}) ICollection`\n\n对Collection中的每个函数都进行一次函数调用，并将返回值组装成ICollection\n\n这个回调函数形如： `func(item interface{}, key int) interface{}`\n\n如果希望在某此调用的时候中止，就在此次调用的时候设置Collection的Error，就可以中止，且此次回调函数生成的结构不合并到最终生成的ICollection。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4})\nnewIntColl := intColl.Map(func(item interface{}, key int) interface{} {\n    v := item.(int)\n    return v * 2\n})\nnewIntColl.DD()\n\nif newIntColl.Count() != 4 {\n    t.Fatal(\"Map错误\")\n}\n\nnewIntColl2 := intColl.Map(func(item interface{}, key int) interface{} {\n    v := item.(int)\n\n    if key \u003e 2 {\n        intColl.SetErr(errors.New(\"break\"))\n        return nil\n    }\n\n    return v * 2\n})\nnewIntColl2.DD()\n\n/*\nIntCollection(4):{\n\t0:\t2\n\t1:\t4\n\t2:\t6\n\t3:\t8\n}\nIntCollection(3):{\n\t0:\t2\n\t1:\t4\n\t2:\t6\n}\n*/\n```\n\n### Mode\n\n`Mode() IMix`\n\n获取Collection中的众数，如果有大于两个的众数，返回第一次出现的那个。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3, 4, 5, 6})\nmode, err := intColl.Mode().ToInt()\n if err != nil {\n     t.Fatal(err.Error())\n }\n if mode != 2 {\n     t.Fatal(\"Mode error\")\n }\n \n intColl = NewIntCollection([]int{1, 2, 2, 3, 4, 4, 5, 6})\n \n mode, err = intColl.Mode().ToInt()\n if err != nil {\n     t.Fatal(err.Error())\n }\n if mode != 2 {\n     t.Fatal(\"Mode error\")\n }\n```\n\n\n\n### Max\n\n`Max() IMix`\n\n获取Collection中的最大元素，必须设置compare函数\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nmax, err := intColl.Max().ToInt()\nif err != nil {\n    t.Fatal(err)\n}\n\nif max != 3 {\n    t.Fatal(\"max错误\")\n}\n\n```\n\n### Min\n\n`Min() IMix`\n\n获取Collection中的最小元素，必须设置compare函数\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nmin, err := intColl.Min().ToInt()\nif err != nil {\n    t.Fatal(err)\n}\n\nif min != 1 {\n    t.Fatal(\"min错误\")\n}\n\n```\n\n\n### Median\n\n`Median() IMix`\n\n获取Collection的中位数，如果Collection个数是单数，返回排序后中间的元素，如果Collection的个数是双数，返回排序后中间两个元素的算数平均数。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nmedian, err := intColl.Median().ToFloat64()\nif err != nil {\n    t.Fatal(err)\n}\n\nif median != 2.0 {\n    t.Fatal(\"Median 错误\" + fmt.Sprintf(\"%v\", median))\n}\n```\n\n### NewEmpty\n\n`NewEmpty(err ...error) ICollection`\n\nNewEmpty方法根据当前的数组，创造出一个同类型的数组，但长度为0\n\n```\nintColl := NewIntCollection([]int{1,2})\nintColl2 := intColl.NewEmpty()\nintColl2.DD()\n\n/*\nIntCollection(0):{\n}\n*/\n```\n\n\n### Nth\n\n`Nth(n int, offset int) ICollection`\n\nNth(n int, offset int) 获取从offset偏移量开始的每第n个，偏移量offset的设置为第一个。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\nret := intColl.Nth(4, 1)\nret.DD()\n\nif ret.Count() != 2 {\n    t.Fatal(\"Nth 错误\")\n}\n\n/*\nIntCollection(2):{\n\t0:\t2\n\t1:\t6\n}\n*/\n```\n\n### Pad\n\n`Pad(start int, def interface{}) ICollection` \n\n填充Collection数组，如果第一个参数大于0，则代表往Collection的右边进行填充，如果第一个参数小于零，则代表往Collection的左边进行填充。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3})\nret := intColl.Pad(5, 0)\nif ret.Err() != nil {\n    t.Fatal(ret.Err().Error())\n}\n\nret.DD()\nif ret.Count() != 5 {\n    t.Fatal(\"Pad 错误\")\n}\n\nret = intColl.Pad(-5, 0)\nif ret.Err() != nil {\n    t.Fatal(ret.Err().Error())\n}\nret.DD()\nif ret.Count() != 5 {\n    t.Fatal(\"Pad 错误\")\n}\n\n/*\nIntCollection(5):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n\t3:\t0\n\t4:\t0\n}\nIntCollection(5):{\n\t0:\t0\n\t1:\t0\n\t2:\t1\n\t3:\t2\n\t4:\t3\n}\n*/\n```\n\n### Pop\n\n`Pop() IMix`\n\n从Collection右侧弹出一个元素\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\npop := intColl.Pop()\nin, err := pop.ToInt()\nif err != nil {\n    t.Fatal(err.Error())\n}\nif in != 6 {\n    t.Fatal(\"Pop 错误\")\n}\nintColl.DD()\nif intColl.Count() != 5 {\n    t.Fatal(\"Pop 后本体错误\")\n}\n\n/*\nIntCollection(5):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n\t3:\t4\n\t4:\t5\n}\n*/\n```\n\n### Push\n\n`Push(item interface{}) ICollection`\n\n往Collection的右侧推入一个元素\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\nintColl.Push(7)\nintColl.DD()\nif intColl.Count() != 7 {\n    t.Fatal(\"Push 后本体错误\")\n}\n\n/*\nIntCollection(7):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n\t3:\t4\n\t4:\t5\n\t5:\t6\n\t6:\t7\n}\n*/\n```\n\n### Prepend\n\n`Prepend(item interface{}) ICollection`\n\n往Collection左侧加入元素\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\nintColl.Prepend(0)\nif intColl.Err() != nil {\n    t.Fatal(intColl.Err().Error())\n}\n\nintColl.DD()\nif intColl.Count() != 7 {\n    t.Fatal(\"Prepend错误\")\n}\n\n/*\nIntCollection(7):{\n\t0:\t0\n\t1:\t1\n\t2:\t2\n\t3:\t3\n\t4:\t4\n\t5:\t5\n\t6:\t6\n}\n*/\n```\n\n### Pluck\n\n`Pluck(key string) ICollection`\n\n将对象数组中的某个元素提取出来组成一个新的Collection。这个元素必须是Public元素\n\n注：这个函数只对ObjCollection生效。\n\n```go\ntype Foo struct {\n\tA string\n}\n\nfunc TestObjCollection_Pluck(t *testing.T) {\n\ta1 := Foo{A: \"a1\"}\n\ta2 := Foo{A: \"a2\"}\n\n\tobjColl := NewObjCollection([]Foo{a1, a2})\n\n\tobjColl.Pluck(\"A\").DD()\n}\n\n/*\nStrCollection(2):{\n\t0:\ta1\n\t1:\ta2\n}\n*/\n```\n\n### Reject\n\n`Reject(func(item interface{}, key int) bool) ICollection`\n\n将满足过滤条件的元素删除\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5})\nretColl := intColl.Reject(func(item interface{}, key int) bool {\n    i := item.(int)\n    return i \u003e 3\n})\nif retColl.Count() != 3 {\n    t.Fatal(\"Reject 重复错误\")\n}\n\nretColl.DD()\n\n/*\nIntCollection(3):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n}\n*/\n```\n\n### Reduce\n\n`Reduce(func(carry IMix, item IMix) IMix) IMix`\n\n对Collection中的所有元素进行聚合计算。\n\n如果希望在某次调用的时候中止，在此次调用的时候设置Collection的Error，就可以中止调用。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4})\nsumMix := intColl.Reduce(func(carry IMix, item IMix) IMix {\n    carryInt, _ := carry.ToInt()\n    itemInt, _ := item.ToInt()\n    return NewMix(carryInt + itemInt)\n})\n\nsumMix.DD()\n\nsum, err := sumMix.ToInt()\nif err != nil {\n    t.Fatal(err.Error())\n}\nif sum != 10 {\n    t.Fatal(\"Reduce计算错误\")\n}\n\n/*\nIMix(int): 10 \n*/\n```\n\n### Random\n\n`Random() IMix`\n\n随机获取Collection中的元素，随机数种子使用时间戳\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\nout := intColl.Random()\nout.DD()\n\n_, err := out.ToInt()\nif err != nil {\n    t.Fatal(err.Error())\n}\n\n/*\nIMix(int): 5 \n*/\n```\n\n### Reverse\n\n`Reverse() ICollection`\n\n将Collection数组进行转置\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5, 6})\nvs := intColl.Reverse()\nvs.DD()\n\n/*\nIntCollection(6):{\n\t0:\t6\n\t1:\t5\n\t2:\t4\n\t3:\t3\n\t4:\t2\n\t5:\t1\n}\n*/\n```\n\n### Search\n\n`Search(item interface{}) int`\n\n查找Collection中第一个匹配查询元素的下标，如果存在，返回下标；如果不存在，返回-1\n\n*注意* 此函数要求设置compare方法，基础元素数组（int, int64, float32, float64, string）可直接调用！\n\n```go\nintColl := NewIntCollection([]int{1,2})\nif intColl.Search(2) != 1 {\n    t.Fatal(\"Search 错误\")\n}\n\nintColl = NewIntCollection([]int{1,2, 3, 3, 2})\nif intColl.Search(3) != 2 {\n    t.Fatal(\"Search 重复错误\")\n}\n```\n\n### Slice\n\n`Slice(...int) ICollection`\n\n获取Collection中的片段，可以有两个参数或者一个参数。\n\n如果是两个参数，第一个参数代表开始下标，第二个参数代表结束下标，当第二个参数为-1时候，就代表到Collection结束。\n\n如果是一个参数，则代表从这个开始下标一直获取到Collection结束的片段。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 3, 4, 5})\nretColl := intColl.Slice(2)\nif retColl.Count() != 3 {\n    t.Fatal(\"Slice 错误\")\n}\n\nretColl.DD()\n\nretColl = intColl.Slice(2,2)\nif retColl.Count() != 2 {\n    t.Fatal(\"Slice 两个参数错误\")\n}\n\nretColl.DD()\n\nretColl = intColl.Slice(2, -1)\nif retColl.Count() != 3 {\n    t.Fatal(\"Slice第二个参数为-1错误\")\n}\n\nretColl.DD()\n\n/*\nIntCollection(3):{\n\t0:\t3\n\t1:\t4\n\t2:\t5\n}\nIntCollection(2):{\n\t0:\t3\n\t1:\t4\n}\nIntCollection(3):{\n\t0:\t3\n\t1:\t4\n\t2:\t5\n}\n*/\n\n```\n\n\n### Shuffle\n\n`Shuffle() ICollection`\n\n将Collection中的元素进行乱序排列，随机数种子使用时间戳\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nnewColl := intColl.Shuffle()\nnewColl.DD()\nif newColl.Err() != nil {\n    t.Fatal(newColl.Err())\n}\n\n/*\nIntCollection(4):{\n\t0:\t1\n\t1:\t3\n\t2:\t2\n\t3:\t2\n}\n*/\n```\n\n### Sort\n\n`Sort() ICollection`\n\n将Collection中的元素进行升序排列输出，必须设置compare函数\n\n```go\nintColl := NewIntCollection([]int{2, 4, 3})\nintColl2 := intColl.Sort()\nif intColl2.Err() != nil {\n    t.Fatal(intColl2.Err())\n}\nintColl2.DD()\n\n/*\nIntCollection(3):{\n\t0:\t2\n\t1:\t3\n\t2:\t4\n}\n*/\n```\n\n### SortDesc\n\n`SortDesc() ICollection`\n\n将Collection中的元素按照降序排列输出，必须设置compare函数\n\n```go\nintColl := NewIntCollection([]int{2, 4, 3})\nintColl2 := intColl.SortDesc()\nif intColl2.Err() != nil {\n    t.Fatal(intColl2.Err())\n}\nintColl2.DD()\n\n/*\nIntCollection(3):{\n\t0:\t4\n\t1:\t3\n\t2:\t2\n}\n*/\n```\n\n\n### Sum\n\n`Sum() IMix`\n\n返回Collection中的元素的和\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\nintColl.Sum().DD()\nsum, err := intColl.Sum().ToInt()\nif err != nil {\n    t.Fatal(err)\n}\n\nif sum != 8 {\n    t.Fatal(\"sum 错误\")\n}\n\n/*\nIMix(int): 8 \n*/\n```\n\n### SortBy\n\n`SortBy(key string) ICollection`\n\n根据对象数组中的某个元素进行Collection升序排列。这个元素必须是Public元素\n\n注：这个函数只对ObjCollection生效。这个对象数组的某个元素必须是基础类型。\n\n```go\ntype Foo struct {\n\tA string\n\tB int\n}\n\nfunc TestObjCollection_SortBy(t *testing.T) {\n\ta1 := Foo{A: \"a1\", B: 3}\n\ta2 := Foo{A: \"a2\", B: 2}\n\n\tobjColl := NewObjCollection([]Foo{a1, a2})\n\n\tnewObjColl := objColl.SortBy(\"B\")\n\n\tnewObjColl.DD()\n\n\tobj, err := newObjColl.Index(0).ToInterface()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tfoo := obj.(Foo)\n\tif foo.B != 2 {\n\t\tt.Fatal(\"SortBy error\")\n\t}\n}\n\n/*\nObjCollection(2)(collection.Foo):{\n\t0:\t{A:a2 B:2}\n\t1:\t{A:a1 B:3}\n}\n*/\n```\n\n### SortByDesc\n\n`SortByDesc(key string) ICollection`\n\n根据对象数组中的某个元素进行Collection降序排列。这个元素必须是Public元素\n\n注：这个函数只对ObjCollection生效。这个对象数组的某个元素必须是基础类型。\n\n```go\ntype Foo struct {\n\tA string\n\tB int\n}\n\nfunc TestObjCollection_SortByDesc(t *testing.T) {\n\ta1 := Foo{A: \"a1\", B: 2}\n\ta2 := Foo{A: \"a2\", B: 3}\n\n\tobjColl := NewObjCollection([]Foo{a1, a2})\n\n\tnewObjColl := objColl.SortByDesc(\"B\")\n\n\tnewObjColl.DD()\n\n\tobj, err := newObjColl.Index(0).ToInterface()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tfoo := obj.(Foo)\n\tif foo.B != 3 {\n\t\tt.Fatal(\"SortBy error\")\n\t}\n}\n\n/*\nObjCollection(2)(collection.Foo):{\n\t0:\t{A:a2 B:3}\n\t1:\t{A:a1 B:2}\n}\n*/\n```\n\n------------\n\n### ToInts\n\n`ToInts() ([]int, error)`\n\n将Collection变化为int数组，如果Collection内的元素类型不符合，或者Collection有错误，则返回错误。\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\narr, err := intColl.ToInts()\nif err != nil {\n    t.Fatal(err)\n}\nif len(arr) != 4 {\n    t.Fatal(errors.New(\"ToInts error\"))\n}\n```\n\n### ToInt64s\n\n`ToInt64s() ([]int64, error)`\n\n将Collection变化为int64数组，如果Collection内的元素类型不符合，或者Collection有错误，则返回错误。\n\n```go\nintColl := NewInt64Collection([]int{1, 2, 2, 3})\narr, err := intColl.ToInts()\nif err != nil {\n    t.Fatal(err)\n}\nif len(arr) != 4 {\n    t.Fatal(errors.New(\"ToInts error\"))\n}\n```\n\n### ToFloat64s\n\n`ToFloat64s() ([]float64, error)`\n\n将Collection变化为float64数组，如果Collection内的元素类型不符合，或者Collection有错误，则返回错误。\n\n```go\narr := NewFloat64Collection([]float64{1.0 ,2.0,3.0,4.0,5.0})\n\narr.DD()\n\nmax, err := arr.Max().ToFloat64()\nif err != nil {\n    t.Fatal(err)\n}\n\nif max != 5 {\n    t.Fatal(errors.New(\"max error\"))\n}\n\n\narr2 := arr.Filter(func(obj interface{}, index int) bool {\n    val := obj.(float64)\n    if val \u003e 2.0 {\n        return true\n    }\n    return false\n})\nif arr2.Count() != 3 {\n    t.Fatal(errors.New(\"filter error\"))\n}\n\nout, err := arr2.ToFloat64s()\nif err != nil || len(out) != 3 {\n    t.Fatal(errors.New(\"to float64s error\"))\n}\n\n```\n\n### ToFloat32s\n\n`ToFloat32s() ([]float32, error)`\n\n将Collection变化为float32数组，如果Collection内的元素类型不符合，或者Collection有错误，则返回错误。\n\n```go\narr := NewFloat32Collection([]float32{1.0 ,2.0,3.0,4.0,5.0})\n\narr.DD()\n\nmax, err := arr.Max().ToFloat32()\nif err != nil {\n    t.Fatal(err)\n}\n\nif max != 5 {\n    t.Fatal(errors.New(\"max error\"))\n}\n\n\narr2 := arr.Filter(func(obj interface{}, index int) bool {\n    val := obj.(float32)\n    if val \u003e 2.0 {\n        return true\n    }\n    return false\n})\nif arr2.Count() != 3 {\n    t.Fatal(errors.New(\"filter error\"))\n}\n\nout, err := arr2.ToFloat32s()\nif err != nil || len(out) != 3 {\n    t.Fatal(errors.New(\"to float32s error\"))\n}\n```\n\n### ToMixs\n\n`ToMixs() ([]IMix, error)`\n\n将Collection变化为Mix数组，如果Collection内的元素类型不符合，或者Collection有错误，则返回错误\n\n```go\nintColl := NewIntCollection([]int{1, 2, 2, 3})\narr, err := intColl.ToMixs()\nif err != nil {\n    t.Fatal(err)\n}\nif len(arr) != 4 {\n    t.Fatal(errors.New(\"ToInts error\"))\n}\n```\n\n### ToInterfaces\n\n`ToInterfaces() ([]interface{}, error)`\n\n将Collection变化为Interface{}数组，如果Collection内的元素类型不符合，或者Collection有错误，则返回错误\n\n### Unique\n\n`Unique() ICollection`\n\n将Collection中重复的元素进行合并，返回唯一的一个数组。\n\n*注意* 此函数要求设置compare方法，基础元素数组（int, int64, float32, float64, string）可直接调用！\n\n```go\nintColl := NewIntCollection([]int{1,2, 3, 3, 2})\nuniqColl := intColl.Unique()\nif uniqColl.Count() != 3 {\n    t.Fatal(\"Unique 重复错误\")\n}\n\nuniqColl.DD()\n/*\nIntCollection(3):{\n\t0:\t1\n\t1:\t2\n\t2:\t3\n}\n*/\n```\n\n\n-------------\n```\n$ go test -bench=. -run=non                         \n\ngoos: darwin\ngoarch: amd64\npkg: github.com/jianfengye/collection\nBenchmark_Append-12        \t 3512688\t       387 ns/op\nBenchmark_Contain-12       \t 6727482\t       179 ns/op\nBenchmark_Copy-12          \t 7260177\t       159 ns/op\nBenchmark_Diff-12          \t 2310327\t       522 ns/op\nBenchmark_Each-12          \t 7784914\t       154 ns/op\nBenchmark_Every-12         \t 7602790\t       157 ns/op\nBenchmark_ForPage-12       \t 2355352\t       515 ns/op\nBenchmark_Filter-12        \t 1356804\t       876 ns/op\nBenchmark_First-12         \t19379992\t        61.8 ns/op\nBenchmark_Index-12         \t19259961\t        62.1 ns/op\nBenchmark_IsEmpty-12       \t162860646\t         7.33 ns/op\nBenchmark_IsNotEmpty-12    \t163036106\t         7.36 ns/op\nBenchmark_Join-12          \t 4705460\t       255 ns/op\nBenchmark_Last-12          \t15544176\t        76.8 ns/op\nBenchmark_Merge-12         \t 1372609\t       872 ns/op\nBenchmark_Map-12           \t 2752177\t       439 ns/op\nBenchmark_Max-12           \t 3218686\t       372 ns/op\nBenchmark_Min-12           \t 3233270\t       372 ns/op\nBenchmark_Median-12        \t 1379985\t       869 ns/op\nBenchmark_Nth-12           \t 2360064\t       503 ns/op\nBenchmark_Pop-12           \t 1454916\t       834 ns/op\nBenchmark_Push-12          \t 3629934\t       346 ns/op\nBenchmark_Prepend-12       \t   10000\t    376298 ns/op\nBenchmark_Pluck-12         \t 2531895\t       469 ns/op\nBenchmark_Reject-12        \t 4184707\t       286 ns/op\nBenchmark_Random-12        \t  142698\t      8397 ns/op\nBenchmark_Reverse-12       \t 1324262\t       903 ns/op\nBenchmark_Slice-12         \t 2272142\t       515 ns/op\nBenchmark_Search-12        \t 6484984\t       186 ns/op\nBenchmark_Sort-12          \t 3627673\t       333 ns/op\nBenchmark_SortDesc-12      \t 3565390\t       331 ns/op\nBenchmark_Shuffle-12       \t  128826\t      9320 ns/op\nBenchmark_SortBy-12        \t564669482\t         2.13 ns/op\nBenchmark_SortByDesc-12    \t595491585\t         2.03 ns/op\nBenchmark_Unique-12        \t 1219267\t       979 ns/op\nPASS\nok  \tgithub.com/jianfengye/collection\t59.484s\n```\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nLicense\n------------\n`collection` is licensed under [Apache License](LICENSE).\n\n## Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n\u003ca href=\"https://github.com/jianfengye/collection/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/collection/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/collection#backer)]\n\n\u003ca href=\"https://opencollective.com/collection#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/backers.svg?width=890\"\u003e\u003c/a\u003e\n\n\n## Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/collection#sponsor)]\n\n\u003ca href=\"https://opencollective.com/collection/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/collection/sponsor/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/collection/sponsor/9/avatar.svg\"\u003e\u003c/a\u003e\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidi%2Fcollection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdidi%2Fcollection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdidi%2Fcollection/lists"}