1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-23 13:52:26 +08:00

Compare commits

..

11 Commits

Author SHA1 Message Date
dudaodong
205fedb197 release v2.1.11 2022-12-04 11:11:05 +08:00
dudaodong
4c864da62d doc: update readme file 2022-12-04 11:10:19 +08:00
dudaodong
263ab7e316 clean code 2022-12-03 14:41:58 +08:00
dudaodong
809b7a53df doc: update docment for slice package 2022-12-03 14:33:15 +08:00
dudaodong
61c43daabb doc: add doc for Count and CountBy function 2022-12-03 14:20:37 +08:00
dudaodong
18914ee2cd feat: add deprecat IntSlice, InterfaceSlice and StringSlice 2022-12-03 14:00:44 +08:00
dudaodong
0a8058956f feat: add Count and CountBy function 2022-12-03 13:04:12 +08:00
dudaodong
a044da7d2f refactor: clean code 2022-12-03 12:58:25 +08:00
dudaodong
f8b785c4cb doc: add doc for Sort and SortBy 2022-12-02 15:47:16 +08:00
dudaodong
82c8a04c35 make SortByField function deprecate 2022-12-02 15:17:08 +08:00
dudaodong
280ecb5cef feat: add SortBy function for slice 2022-12-02 14:53:57 +08:00
7 changed files with 463 additions and 138 deletions

View File

@@ -4,7 +4,7 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf) ![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.1.10-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-2.1.11-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2) [![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml) [![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -372,11 +372,11 @@ import "github.com/duke-git/lancet/v2/netutil"
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#DecodeResponse) - [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#DecodeResponse)
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#StructToUrlValues) - [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#StructToUrlValues)
- [HttpGet<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet) - [HttpGet<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpGet)
- [HttpDelete<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete) - [HttpDelete<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpDelete)
- [HttpPost<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost) - [HttpPost<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPost)
- [HttpPut<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut) - [HttpPut<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPut)
- [HttpPatch<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch) - [HttpPatch<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse) - [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil.md#ParseHttpResponse)
### 14. Random package implements some basic functions to generate random int and string. ### 14. Random package implements some basic functions to generate random int and string.
@@ -425,6 +425,7 @@ import "github.com/duke-git/lancet/v2/slice"
- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Compact) - [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Compact)
- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Concat) - [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Concat)
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count) - [Count](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Count)
- [CountBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#CountBy)
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference) - [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Difference)
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy) - [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceBy)
- [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith) - [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith)
@@ -441,21 +442,25 @@ import "github.com/duke-git/lancet/v2/slice"
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach) - [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ForEach)
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy) - [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupBy)
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupWith) - [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#GroupWith)
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice) - [IntSlice<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IntSlice)
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice) - [InterfaceSlice<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InterfaceSlice)
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection) - [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Intersection)
- [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertAt) - [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice.md#InsertAt)
- [IndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IndexOf) - [IndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice.md#IndexOf)
- [LastIndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice.md#LastIndexOf) - [LastIndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice.md#LastIndexOf)
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map) - [Map](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Map)
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Merge)
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse) - [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reverse)
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce) - [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Reduce)
- [Replace](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Replace) - [Replace](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Replace)
- [ReplaceAll](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReplaceAll) - [ReplaceAll](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ReplaceAll)
- [Repeat](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Repeat)
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle) - [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Shuffle)
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField) - [Sort](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Sort)
- [SortBy](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortBy)
- [SortByField<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SortByField)
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some) - [Some](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Some)
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice) - [StringSlice<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice.md#StringSlice)
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SymmetricDifference) - [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice.md#SymmetricDifference)
- [ToSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ToSlice) - [ToSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ToSlice)
- [ToSlicePointer](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ToSlicePointer) - [ToSlicePointer](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ToSlicePointer)

View File

@@ -4,7 +4,7 @@
<br/> <br/>
![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf) ![Go version](https://img.shields.io/badge/go-%3E%3Dv1.18-9cf)
[![Release](https://img.shields.io/badge/release-2.1.10-green.svg)](https://github.com/duke-git/lancet/releases) [![Release](https://img.shields.io/badge/release-2.1.11-green.svg)](https://github.com/duke-git/lancet/releases)
[![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2) [![GoDoc](https://godoc.org/github.com/duke-git/lancet/v2?status.svg)](https://pkg.go.dev/github.com/duke-git/lancet/v2)
[![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/duke-git/lancet/v2)](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
[![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml) [![test](https://github.com/duke-git/lancet/actions/workflows/codecov.yml/badge.svg?branch=main&event=push)](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
@@ -371,11 +371,11 @@ import "github.com/duke-git/lancet/v2/netutil"
- [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#DecodeResponse) - [DecodeResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#DecodeResponse)
- [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#StructToUrlValues) - [StructToUrlValues](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#StructToUrlValues)
- [HttpGet<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet) - [HttpGet<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpGet)
- [HttpDelete<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete) - [HttpDelete<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpDelete)
- [HttpPost<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost) - [HttpPost<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPost)
- [HttpPut<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut) - [HttpPut<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPut)
- [HttpPatch<sup>Deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch) - [HttpPatch<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#HttpPatch)
- [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse) - [ParseHttpResponse](https://github.com/duke-git/lancet/blob/main/docs/netutil_zh-CN.md#ParseHttpResponse)
### 14. random 随机数生成器包,可以生成随机[]bytes, int, string。 ### 14. random 随机数生成器包,可以生成随机[]bytes, int, string。
@@ -424,6 +424,7 @@ import "github.com/duke-git/lancet/v2/slice"
- [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Compact) - [Compact](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Compact)
- [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Concat) - [Concat](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Concat)
- [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count) - [Count](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Count)
- [CountBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#CountBy)
- [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference) - [Difference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Difference)
- [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy) - [DifferenceBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#DifferenceBy)
- [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith) - [DifferenceWith](https://github.com/duke-git/lancet/blob/main/docs/slice.md#DifferenceWith)
@@ -438,21 +439,25 @@ import "github.com/duke-git/lancet/v2/slice"
- [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach) - [ForEach](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ForEach)
- [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy) - [GroupBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupBy)
- [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupWith) - [GroupWith](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#GroupWith)
- [IntSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice) - [IntSlice<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IntSlice)
- [InterfaceSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice) - [InterfaceSlice<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InterfaceSlice)
- [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection) - [Intersection](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Intersection)
- [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertAt) - [InsertAt](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#InsertAt)
- [IndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IndexOf) - [IndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#IndexOf)
- [LastIndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#LastIndexOf) - [LastIndexOf](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#LastIndexOf)
- [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map) - [Map](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Map)
- [Merge](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Merge)
- [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse) - [Reverse](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reverse)
- [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce) - [Reduce](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Reduce)
- [Replace](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Replace) - [Replace](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Replace)
- [ReplaceAll](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReplaceAll) - [ReplaceAll](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ReplaceAll)
- [Repeat](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Repeat)
- [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle) - [Shuffle](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Shuffle)
- [SortByField](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField) - [Sort](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Sort)
- [SortBy](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortBy)
- [SortByField<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SortByField)
- [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some) - [Some](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Some)
- [StringSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice) - [StringSlice<sup>deprecated</sup>](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#StringSlice)
- [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SymmetricDifference) - [SymmetricDifference](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#SymmetricDifference)
- [ToSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ToSlice) - [ToSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ToSlice)
- [ToSlicePointer](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ToSlicePointer) - [ToSlicePointer](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ToSlicePointer)

View File

@@ -29,6 +29,7 @@ import (
- [Compact](#Compact) - [Compact](#Compact)
- [Concat](#Concat) - [Concat](#Concat)
- [Count](#Count) - [Count](#Count)
- [CountBy](#CountBy)
- [Difference](#Difference) - [Difference](#Difference)
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith) - [DifferenceWith](#DifferenceWith)
@@ -45,8 +46,8 @@ import (
- [ForEach](#ForEach) - [ForEach](#ForEach)
- [GroupBy](#GroupBy) - [GroupBy](#GroupBy)
- [GroupWith](#GroupWith) - [GroupWith](#GroupWith)
- [IntSlice](#IntSlice) - [IntSlice<sup>deprecated</sup>](#IntSlice)
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice<sup>deprecated</sup>](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertAt](#InsertAt) - [InsertAt](#InsertAt)
- [IndexOf](#IndexOf) - [IndexOf](#IndexOf)
@@ -59,9 +60,11 @@ import (
- [ReplaceAll](#ReplaceAll) - [ReplaceAll](#ReplaceAll)
- [Repeat](#Repeat) - [Repeat](#Repeat)
- [Shuffle](#Shuffle) - [Shuffle](#Shuffle)
- [SortByField](#SortByField) - [Sort](#Sort)
- [SortBy](#SortBy)
- [SortByField<sup>deprecated</sup>](#SortByField)
- [Some](#Some) - [Some](#Some)
- [StringSlice](#StringSlice) - [StringSlice<sup>deprecated</sup>](#StringSlice)
- [SymmetricDifference](#SymmetricDifference) - [SymmetricDifference](#SymmetricDifference)
- [ToSlice](#ToSlice) - [ToSlice](#ToSlice)
- [ToSlicePointer](#ToSlicePointer) - [ToSlicePointer](#ToSlicePointer)
@@ -79,12 +82,12 @@ import (
### <span id="AppendIfAbsent">AppendIfAbsent</span> ### <span id="AppendIfAbsent">AppendIfAbsent</span>
<p>If slice doesn't contain the value, append it to the slice.</p> <p>If slice doesn't contain the item, append it to the slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func AppendIfAbsent[T comparable](slice []T, value T) []T func AppendIfAbsent[T comparable](slice []T, item T) []T
``` ```
<b>Example:</b> <b>Example:</b>
@@ -107,12 +110,12 @@ func main() {
### <span id="Contain">Contain</span> ### <span id="Contain">Contain</span>
<p>Check if the value is in the slice or not.</p> <p>Check if the target value is in the slice or not.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Contain[T comparable](slice []T, value T) bool func Contain[T comparable](slice []T, target T) bool
``` ```
<b>Example:</b> <b>Example:</b>
@@ -136,7 +139,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ContainSubSlice[T comparable](slice, subslice []T) bool func ContainSubSlice[T comparable](slice, subSlice []T) bool
``` ```
<b>Example:</b> <b>Example:</b>
@@ -204,12 +207,12 @@ func main() {
### <span id="Concat">Concat</span> ### <span id="Concat">Concat</span>
<p>Creates a new slice concatenating slice with any additional slices and/or values.</p> <p>Creates a new slice concatenating slice with any additional slices.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Concat[T any](slice []T, values ...[]T) []T func Concat[T any](slice []T, slices ...[]T) []T
``` ```
<b>Example:</b> <b>Example:</b>
@@ -231,12 +234,38 @@ func main() {
### <span id="Count">Count</span> ### <span id="Count">Count</span>
<p>Count iterates over elements of slice, returns a count of all matched elements.</p> <p>Returns the number of occurrences of the given item in the slice.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Count[T any](slice []T, predicate func(index int, t T) bool) int func Count[T comparable](slice []T, item T) int
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 3, 4, 5}
fmt.Println(slice.Count(nums, 1)) //1
fmt.Println(slice.Count(nums, 3)) //2
}
```
### <span id="CountBy">CountBy</span>
<p>Iterates over elements of slice with predicate function, returns the number of all matched elements.</p>
<b>Signature:</b>
```go
func CountBy[T any](slice []T, predicate func(index int, item T) bool) int
``` ```
<b>Example:</b> <b>Example:</b>
@@ -249,15 +278,16 @@ import (
func main() { func main() {
nums := []int{1, 2, 3, 4, 5, 6} nums := []int{1, 2, 3, 4, 5, 6}
evenFunc := func(i, num int) bool { evenFunc := func(_, num int) bool {
return (num % 2) == 0 return (num % 2) == 0
} }
res := slice.Count(nums, evenFunc) res := slice.CountBy(nums, evenFunc)
fmt.Println(res) //3 fmt.Println(res) //3
} }
``` ```
### <span id="Difference">Difference</span> ### <span id="Difference">Difference</span>
<p>Creates an slice of whose element not included in the other given slice.</p> <p>Creates an slice of whose element not included in the other given slice.</p>
@@ -716,11 +746,12 @@ func main() {
return math.Floor(num) return math.Floor(num)
} }
res := slice.GroupWith(nums, floor) res := slice.GroupWith(nums, floor)
fmt.Println(res) //map[float64][]float64{ 4: {4.2}, 6: {6.1, 6.3},} fmt.Println(res) //map[float64][]float64{ 4: {4.2}, 6: {6.1, 6.3},}
} }
``` ```
### <span id="IntSlice">IntSlice</span> ### <span id="IntSlice">IntSlice (Deprecated: use generic feature of go1.18+ for replacement)</span>
<p>Convert interface slice to int slice.</p> <p>Convert interface slice to int slice.</p>
@@ -745,7 +776,7 @@ func main() {
} }
``` ```
### <span id="InterfaceSlice">InterfaceSlice</span> ### <span id="InterfaceSlice">InterfaceSlice (Deprecated: use generic feature of go1.18+ for replacement)</span>
<p>Convert value to interface slice.</p> <p>Convert value to interface slice.</p>
@@ -828,12 +859,12 @@ func main() {
### <span id="IndexOf">IndexOf</span> ### <span id="IndexOf">IndexOf</span>
<p>Returns the index at which the first occurrence of a value is found in a slice or return -1 if the value cannot be found.</p> <p>Returns the index at which the first occurrence of a item is found in a slice or return -1 if the item cannot be found.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func IndexOf[T comparable](slice []T, value T) int func IndexOf[T comparable](slice []T, item T) int
``` ```
<b>Example:</b> <b>Example:</b>
@@ -856,12 +887,12 @@ func main() {
### <span id="LastIndexOf">LastIndexOf</span> ### <span id="LastIndexOf">LastIndexOf</span>
<p>Returns the index at which the last occurrence of a value is found in a slice or return -1 if the value cannot be found.</p> <p>Returns the index at which the last occurrence of a item is found in a slice or return -1 if the item cannot be found.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func LastIndexOf[T comparable](slice []T, value T) int func LastIndexOf[T comparable](slice []T, item T) int
``` ```
<b>Example:</b> <b>Example:</b>
@@ -1099,7 +1130,94 @@ func main() {
} }
``` ```
### <span id="SortByField">SortByField</span> ### <span id="Sort">Sort</span>
<p>Sorts a slice of any ordered type(number or string), use quick sort algrithm. Default sort order is ascending (asc), if want descending order, set param `sortOrder` to `desc`. Ordered type: number(all ints uints floats) or string.
</p>
<b>Signature:</b>
```go
func Sort[T lancetconstraints.Ordered](slice []T, sortOrder ...string)
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
numbers := []int{1, 4, 3, 2, 5}
slice.Sort(numbers)
fmt.Println(numbers) //{1,2,3,4,5}
slice.Sort(numbers, "desc")
fmt.Println(numbers) //{5,4,3,2,1}
strings := []string{"a", "d", "c", "b", "e"}
slice.Sort(strings)
fmt.Println(strings) //{"a", "b", "c", "d", "e"}
slice.Sort(strings, "desc")
fmt.Println(strings) //{"e", "d", "c", "b", "a"}
}
```
### <span id="SortBy">SortBy</span>
<p>Sorts the slice in ascending order as determined by the less function. This sort is not guaranteed to be stable.<p>
<b>Signature:</b>
```go
func SortBy[T any](slice []T, less func(a, b T) bool)
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
numbers := []int{1, 4, 3, 2, 5}
slice.SortBy(numbers, func(a, b int) bool {
return a < b
})
fmt.Println(numbers) //{1, 2, 3, 4, 5}
type User struct {
Name string
Age uint
}
users := []User{
{Name: "a", Age: 21},
{Name: "b", Age: 15},
{Name: "c", Age: 100}}
slice.SortBy(users, func(a, b User) bool {
return a.Age < b.Age
})
fmt.Printf("sort users by age: %v", users)
// output
// [{b 15} {a 21} {c 100}]
}
```
### <span id="SortByField">SortByField (Deprecated: use Sort and SortBy for replacement)</span>
<p>Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc</p> <p>Sort struct slice by field. Slice element should be struct, field type should be int, uint, string, or bool. Default sort type is ascending (asc), if descending order, set sortType to desc</p>
@@ -1171,7 +1289,7 @@ func main() {
} }
``` ```
### <span id="StringSlice">StringSlice</span> ### <span id="StringSlice">StringSlice (Deprecated: use generic feature of go1.18+ for replacement)</span>
<p>Convert interface slice to string slice.</p> <p>Convert interface slice to string slice.</p>
@@ -1227,12 +1345,12 @@ func main() {
### <span id="ToSlice">ToSlice</span> ### <span id="ToSlice">ToSlice</span>
<p>Returns a slices of a variable parameter transformation</p> <p>Creates a slice of give items.</p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToSlice[T any](value ...T) []T func ToSlice[T any](items ...T) []T
``` ```
<b>Example:</b> <b>Example:</b>
@@ -1256,7 +1374,7 @@ func main() {
<b>Signature:</b> <b>Signature:</b>
```go ```go
func ToSlicePointer[T any](value ...T) []*T func ToSlicePointer[T any](items ...T) []*T
``` ```
<b>Example:</b> <b>Example:</b>
@@ -1407,12 +1525,12 @@ func main() {
### <span id="Without">Without</span> ### <span id="Without">Without</span>
<p>Creates a slice excluding all given values. </p> <p>Creates a slice excluding all given items. </p>
<b>Signature:</b> <b>Signature:</b>
```go ```go
func Without[T comparable](slice []T, values ...T) []T func Without[T comparable](slice []T, items ...T) []T
``` ```
<b>Example:</b> <b>Example:</b>

View File

@@ -31,6 +31,7 @@ import (
- [Compact](#Compact) - [Compact](#Compact)
- [Concat](#Concat) - [Concat](#Concat)
- [Count](#Count) - [Count](#Count)
- [CountBy](#CountBy)
- [Difference](#Difference) - [Difference](#Difference)
- [DifferenceBy](#DifferenceBy) - [DifferenceBy](#DifferenceBy)
- [DifferenceWith](#DifferenceWith) - [DifferenceWith](#DifferenceWith)
@@ -47,8 +48,8 @@ import (
- [ForEach](#ForEach) - [ForEach](#ForEach)
- [GroupBy](#GroupBy) - [GroupBy](#GroupBy)
- [GroupWith](#GroupWith) - [GroupWith](#GroupWith)
- [IntSlice](#IntSlice) - [IntSlice<sup>deprecated</sup>](#IntSlice)
- [InterfaceSlice](#InterfaceSlice) - [InterfaceSlice<sup>deprecated</sup>](#InterfaceSlice)
- [Intersection](#Intersection) - [Intersection](#Intersection)
- [InsertAt](#InsertAt) - [InsertAt](#InsertAt)
- [IndexOf](#IndexOf) - [IndexOf](#IndexOf)
@@ -61,9 +62,11 @@ import (
- [ReplaceAll](#ReplaceAll) - [ReplaceAll](#ReplaceAll)
- [Repeat](#Repeat) - [Repeat](#Repeat)
- [Shuffle](#Shuffle) - [Shuffle](#Shuffle)
- [SortByField](#SortByField) - [Sort](#Sort)
- [SortBy](#SortBy)
- [SortByField<sup>deprecated</sup>](#SortByField)
- [Some](#Some) - [Some](#Some)
- [StringSlice](#StringSlice) - [StringSlice<sup>deprecated</sup>](#StringSlice)
- [SymmetricDifference](#SymmetricDifference) - [SymmetricDifference](#SymmetricDifference)
- [ToSlice](#ToSlice) - [ToSlice](#ToSlice)
- [ToSlicePointer](#ToSlicePointer) - [ToSlicePointer](#ToSlicePointer)
@@ -87,7 +90,7 @@ import (
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func AppendIfAbsent[T comparable](slice []T, value T) []T func AppendIfAbsent[T comparable](slice []T, item T) []T
``` ```
<b>例子:</b> <b>例子:</b>
@@ -115,7 +118,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Contain[T comparable](slice []T, value T) bool func Contain[T comparable](slice []T, target T) bool
``` ```
<b>例子:</b> <b>例子:</b>
@@ -139,7 +142,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ContainSubSlice[T comparable](slice, subslice []T) bool func ContainSubSlice[T comparable](slice, subSlice []T) bool
``` ```
<b>例子:</b> <b>例子:</b>
@@ -207,12 +210,12 @@ func main() {
### <span id="Concat">Concat</span> ### <span id="Concat">Concat</span>
<p>连接values到slice中values类型可以是切片或多个值</p> <p>合并多个slices到slice中</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Concat[T any](slice []T, values ...[]T) []T func Concat[T any](slice []T, slices ...[]T) []T
``` ```
<b>例子:</b> <b>例子:</b>
@@ -234,12 +237,38 @@ func main() {
### <span id="Count">Count</span> ### <span id="Count">Count</span>
<p>遍历切片对每个元素执行函数function. 返回符合函数返回值为true的元素的个数</p> <p>返回切片中指定元素的个数</p>
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Count[T any](slice []T, predicate func(index int, t T) bool) int func Count[T comparable](slice []T, item T) int
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
nums := []int{1, 2, 3, 3, 4, 5}
fmt.Println(slice.Count(nums, 1)) //1
fmt.Println(slice.Count(nums, 3)) //2
}
```
### <span id="CountBy">CountBy</span>
<p>遍历切片对每个元素执行函数predicate. 返回符合函数返回值为true的元素的个数.</p>
<b>函数签名:</b>
```go
func CountBy[T any](slice []T, predicate func(index int, item T) bool) int
``` ```
<b>例子:</b> <b>例子:</b>
@@ -252,11 +281,11 @@ import (
func main() { func main() {
nums := []int{1, 2, 3, 4, 5, 6} nums := []int{1, 2, 3, 4, 5, 6}
evenFunc := func(i, num int) bool { evenFunc := func(_, num int) bool {
return (num % 2) == 0 return (num % 2) == 0
} }
res := slice.Count(nums, evenFunc) res := slice.CountBy(nums, evenFunc)
fmt.Println(res) //3 fmt.Println(res) //3
} }
``` ```
@@ -723,7 +752,7 @@ func main() {
} }
``` ```
### <span id="IntSlice">IntSlice</span> ### <span id="IntSlice">IntSlice (已弃用: 使用go1.18+泛型代替)</span>
<p>将接口切片转换为int切片</p> <p>将接口切片转换为int切片</p>
@@ -748,7 +777,7 @@ func main() {
} }
``` ```
### <span id="InterfaceSlice">InterfaceSlice</span> ### <span id="InterfaceSlice">InterfaceSlice(已弃用: 使用go1.18+泛型代替)</span>
<p>将值转换为接口切片</p> <p>将值转换为接口切片</p>
@@ -836,7 +865,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func IndexOf[T comparable](slice []T, value T) int func IndexOf[T comparable](slice []T, item T) int
``` ```
<b>例子:</b> <b>例子:</b>
@@ -864,7 +893,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func LastIndexOf[T comparable](slice []T, value T) int func LastIndexOf[T comparable](slice []T, item T) int
``` ```
<b>例子:</b> <b>例子:</b>
@@ -1099,7 +1128,93 @@ func main() {
} }
``` ```
### <span id="SortByField">SortByField</span> ### <span id="Sort">Sort</span>
<p>对任何有序类型(数字或字符串)的切片进行排序,使用快速排序算法。 默认排序顺序为升序 (asc),如果需要降序,请将参数 `sortOrder` 设置为 `desc`。 Ordered类型数字所有整数浮点数或字符串。</p>
<b>函数签名:</b>
```go
func Sort[T lancetconstraints.Ordered](slice []T, sortOrder ...string)
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
numbers := []int{1, 4, 3, 2, 5}
slice.Sort(numbers)
fmt.Println(numbers) //{1,2,3,4,5}
slice.Sort(numbers, "desc")
fmt.Println(numbers) //{5,4,3,2,1}
strings := []string{"a", "d", "c", "b", "e"}
slice.Sort(strings)
fmt.Println(strings) //{"a", "b", "c", "d", "e"}
slice.Sort(strings, "desc")
fmt.Println(strings) //{"e", "d", "c", "b", "a"}
}
```
### <span id="SortBy">SortBy</span>
<p>按照less函数确定的升序规则对切片进行排序。排序不保证稳定性</p>
<b>函数签名:</b>
```go
func SortBy[T any](slice []T, less func(a, b T) bool)
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/slice"
)
func main() {
numbers := []int{1, 4, 3, 2, 5}
slice.SortBy(numbers, func(a, b int) bool {
return a < b
})
fmt.Println(numbers) //{1, 2, 3, 4, 5}
type User struct {
Name string
Age uint
}
users := []User{
{Name: "a", Age: 21},
{Name: "b", Age: 15},
{Name: "c", Age: 100}}
slice.SortBy(users, func(a, b User) bool {
return a.Age < b.Age
})
fmt.Printf("sort users by age: %v", users)
// output
// [{b 15} {a 21} {c 100}]
}
```
### <span id="SortByField">SortByField (已弃用: 请使用 Sort或SortBy 代替该方法)</span>
<p>按字段对结构切片进行排序。slice元素应为struct字段类型应为int、uint、string或bool。 默认排序类型是升序asc如果是降序设置 sortType 为 desc</p> <p>按字段对结构切片进行排序。slice元素应为struct字段类型应为int、uint、string或bool。 默认排序类型是升序asc如果是降序设置 sortType 为 desc</p>
@@ -1171,7 +1286,7 @@ func main() {
} }
``` ```
### <span id="StringSlice">StringSlice</span> ### <span id="StringSlice">StringSlice(已弃用: 使用go1.18+泛型代替)</span>
<p>将接口切片转换为字符串切片</p> <p>将接口切片转换为字符串切片</p>
@@ -1232,7 +1347,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToSlice[T any](value ...T) []T func ToSlice[T any](items ...T) []T
``` ```
<b>例子:</b> <b>例子:</b>
@@ -1256,7 +1371,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func ToSlicePointer[T any](value ...T) []*T func ToSlicePointer[T any](items ...T) []*T
``` ```
<b>例子:</b> <b>例子:</b>
@@ -1412,7 +1527,7 @@ func main() {
<b>函数签名:</b> <b>函数签名:</b>
```go ```go
func Without[T comparable](slice []T, values ...T) []T func Without[T comparable](slice []T, items ...T) []T
``` ```
<b>例子:</b> <b>例子:</b>

View File

@@ -25,9 +25,9 @@ func Contain[T comparable](slice []T, target T) bool {
return false return false
} }
// ContainSubSlice check if the slice contain subslice or not // ContainSubSlice check if the slice contain a given subslice or not
func ContainSubSlice[T comparable](slice, subslice []T) bool { func ContainSubSlice[T comparable](slice, subSlice []T) bool {
for _, v := range subslice { for _, v := range subSlice {
if !Contain(slice, v) { if !Contain(slice, v) {
return false return false
} }
@@ -36,7 +36,7 @@ func ContainSubSlice[T comparable](slice, subslice []T) bool {
return true return true
} }
// Chunk creates an slice of elements split into groups the length of size. // Chunk creates a slice of elements split into groups the length of size
func Chunk[T any](slice []T, size int) [][]T { func Chunk[T any](slice []T, size int) [][]T {
result := [][]T{} result := [][]T{}
@@ -63,20 +63,20 @@ func Compact[T comparable](slice []T) []T {
var zero T var zero T
result := []T{} result := []T{}
for _, item := range slice { for _, v := range slice {
if item != zero { if v != zero {
result = append(result, item) result = append(result, v)
} }
} }
return result return result
} }
// Concat creates a new slice concatenating slice with any additional slices and/or values. // Concat creates a new slice concatenating slice with any additional slices.
func Concat[T any](slice []T, values ...[]T) []T { func Concat[T any](slice []T, slices ...[]T) []T {
result := append([]T{}, slice...) result := append([]T{}, slice...)
for _, v := range values { for _, v := range slices {
result = append(result, v...) result = append(result, v...)
} }
@@ -114,7 +114,7 @@ func DifferenceBy[T comparable](slice []T, comparedSlice []T, iteratee func(inde
} }
//DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal). //DifferenceWith accepts comparator which is invoked to compare elements of slice to values. The order and references of result values are determined by the first slice. The comparator is invoked with two arguments: (arrVal, othVal).
func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(value1, value2 T) bool) []T { func DifferenceWith[T any](slice []T, comparedSlice []T, comparator func(item1, item2 T) bool) []T {
result := make([]T, 0) result := make([]T, 0)
getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int { getIndex := func(arr []T, item T, comparison func(v1, v2 T) bool) int {
@@ -159,9 +159,8 @@ func EqualWith[T, U any](slice1 []T, slice2 []U, comparator func(T, U) bool) boo
return false return false
} }
for i, v1 := range slice1 { for i, v := range slice1 {
v2 := slice2[i] if !comparator(v, slice2[i]) {
if !comparator(v1, v2) {
return false return false
} }
} }
@@ -206,6 +205,7 @@ func Some[T any](slice []T, predicate func(index int, item T) bool) bool {
// Filter iterates over elements of slice, returning an slice of all elements pass the predicate function // Filter iterates over elements of slice, returning an slice of all elements pass the predicate function
func Filter[T any](slice []T, predicate func(index int, item T) bool) []T { func Filter[T any](slice []T, predicate func(index int, item T) bool) []T {
result := make([]T, 0) result := make([]T, 0)
for i, v := range slice { for i, v := range slice {
if predicate(i, v) { if predicate(i, v) {
result = append(result, v) result = append(result, v)
@@ -215,13 +215,23 @@ func Filter[T any](slice []T, predicate func(index int, item T) bool) []T {
return result return result
} }
// Count iterates over elements of slice, returns a count of all matched elements // Count returns the number of occurrences of the given item in the slice
func Count[T any](slice []T, predicate func(index int, item T) bool) int { func Count[T comparable](slice []T, item T) int {
if len(slice) == 0 { count := 0
return 0
for _, v := range slice {
if item == v {
count++
}
} }
var count int return count
}
// CountBy iterates over elements of slice with predicate function, returns the number of all matched elements
func CountBy[T any](slice []T, predicate func(index int, item T) bool) int {
count := 0
for i, v := range slice { for i, v := range slice {
if predicate(i, v) { if predicate(i, v) {
count++ count++
@@ -270,11 +280,8 @@ func GroupWith[T any, U comparable](slice []T, iteratee func(item T) U) map[U][]
// Find iterates over elements of slice, returning the first one that passes a truth test on predicate function. // Find iterates over elements of slice, returning the first one that passes a truth test on predicate function.
// If return T is nil then no items matched the predicate func // If return T is nil then no items matched the predicate func
func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) { func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
if len(slice) == 0 {
return nil, false
}
index := -1 index := -1
for i, v := range slice { for i, v := range slice {
if predicate(i, v) { if predicate(i, v) {
index = i index = i
@@ -292,11 +299,8 @@ func Find[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
// FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on predicate function. // FindLast iterates over elements of slice from end to begin, returning the first one that passes a truth test on predicate function.
// If return T is nil then no items matched the predicate func // If return T is nil then no items matched the predicate func
func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) { func FindLast[T any](slice []T, predicate func(index int, item T) bool) (*T, bool) {
if len(slice) == 0 {
return nil, false
}
index := -1 index := -1
for i := len(slice) - 1; i >= 0; i-- { for i := len(slice) - 1; i >= 0; i-- {
if predicate(i, slice[i]) { if predicate(i, slice[i]) {
index = i index = i
@@ -342,8 +346,11 @@ func Flatten(slice any) any {
func FlattenDeep(slice any) any { func FlattenDeep(slice any) any {
sv := sliceValue(slice) sv := sliceValue(slice)
st := sliceElemType(sv.Type()) st := sliceElemType(sv.Type())
tmp := reflect.MakeSlice(reflect.SliceOf(st), 0, 0) tmp := reflect.MakeSlice(reflect.SliceOf(st), 0, 0)
result := flattenRecursive(sv, tmp) result := flattenRecursive(sv, tmp)
return result.Interface() return result.Interface()
} }
@@ -372,6 +379,7 @@ func ForEach[T any](slice []T, iteratee func(index int, item T)) {
// Map creates an slice of values by running each element of slice thru iteratee function. // Map creates an slice of values by running each element of slice thru iteratee function.
func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U { func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
result := make([]U, len(slice), cap(slice)) result := make([]U, len(slice), cap(slice))
for i, v := range slice { for i, v := range slice {
result[i] = iteratee(i, v) result[i] = iteratee(i, v)
} }
@@ -381,7 +389,6 @@ func Map[T any, U any](slice []T, iteratee func(index int, item T) U) []U {
// Reduce creates an slice of values by running each element of slice thru iteratee function. // Reduce creates an slice of values by running each element of slice thru iteratee function.
func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T { func Reduce[T any](slice []T, iteratee func(index int, item1, item2 T) T, initial T) T {
if len(slice) == 0 { if len(slice) == 0 {
return initial return initial
} }
@@ -421,13 +428,16 @@ func ReplaceAll[T comparable](slice []T, old T, new T) []T {
// Repeat creates a slice with length n whose elements are param `item`. // Repeat creates a slice with length n whose elements are param `item`.
func Repeat[T any](item T, n int) []T { func Repeat[T any](item T, n int) []T {
result := make([]T, n) result := make([]T, n)
for i := range result { for i := range result {
result[i] = item result[i] = item
} }
return result return result
} }
// InterfaceSlice convert param to slice of interface. // InterfaceSlice convert param to slice of interface.
// This function is deprecated, use generics feature of go1.18+ for replacement
func InterfaceSlice(slice any) []any { func InterfaceSlice(slice any) []any {
sv := sliceValue(slice) sv := sliceValue(slice)
if sv.IsNil() { if sv.IsNil() {
@@ -443,35 +453,37 @@ func InterfaceSlice(slice any) []any {
} }
// StringSlice convert param to slice of string. // StringSlice convert param to slice of string.
// This function is deprecated, use generics feature of go1.18+ for replacement
func StringSlice(slice any) []string { func StringSlice(slice any) []string {
v := sliceValue(slice) v := sliceValue(slice)
out := make([]string, v.Len()) result := make([]string, v.Len())
for i := 0; i < v.Len(); i++ { for i := 0; i < v.Len(); i++ {
v, ok := v.Index(i).Interface().(string) v, ok := v.Index(i).Interface().(string)
if !ok { if !ok {
panic("invalid element type") panic("invalid element type")
} }
out[i] = v result[i] = v
} }
return out return result
} }
// IntSlice convert param to slice of int. // IntSlice convert param to slice of int.
// This function is deprecated, use generics feature of go1.18+ for replacement
func IntSlice(slice any) []int { func IntSlice(slice any) []int {
sv := sliceValue(slice) sv := sliceValue(slice)
out := make([]int, sv.Len()) result := make([]int, sv.Len())
for i := 0; i < sv.Len(); i++ { for i := 0; i < sv.Len(); i++ {
v, ok := sv.Index(i).Interface().(int) v, ok := sv.Index(i).Interface().(int)
if !ok { if !ok {
panic("invalid element type") panic("invalid element type")
} }
out[i] = v result[i] = v
} }
return out return result
} }
// DeleteAt delete the element of slice from start index to end index - 1. // DeleteAt delete the element of slice from start index to end index - 1.
@@ -589,7 +601,7 @@ func UniqueBy[T comparable](slice []T, iteratee func(item T) T) []T {
return Unique(result) return Unique(result)
} }
// Union creates a slice of unique values, in order, from all given slices. // Union creates a slice of unique elements, in order, from all given slices.
func Union[T comparable](slices ...[]T) []T { func Union[T comparable](slices ...[]T) []T {
result := []T{} result := []T{}
contain := map[T]struct{}{} contain := map[T]struct{}{}
@@ -628,14 +640,14 @@ func UnionBy[T any, V comparable](predicate func(item T) V, slices ...[]T) []T {
func Merge[T any](slices ...[]T) []T { func Merge[T any](slices ...[]T) []T {
result := make([]T, 0) result := make([]T, 0)
for _, item := range slices { for _, v := range slices {
result = append(result, item...) result = append(result, v...)
} }
return result return result
} }
// Intersection creates a slice of unique values that included by all slices. // Intersection creates a slice of unique elements that included by all slices.
func Intersection[T comparable](slices ...[]T) []T { func Intersection[T comparable](slices ...[]T) []T {
if len(slices) == 0 { if len(slices) == 0 {
return []T{} return []T{}
@@ -646,8 +658,8 @@ func Intersection[T comparable](slices ...[]T) []T {
reducer := func(sliceA, sliceB []T) []T { reducer := func(sliceA, sliceB []T) []T {
hashMap := make(map[T]int) hashMap := make(map[T]int)
for _, val := range sliceA { for _, v := range sliceA {
hashMap[val] = 1 hashMap[v] = 1
} }
out := make([]T, 0) out := make([]T, 0)
@@ -725,9 +737,16 @@ func Sort[T lancetconstraints.Ordered](slice []T, sortOrder ...string) {
} }
} }
// SortBy sorts the slice in ascending order as determined by the less function.
// This sort is not guaranteed to be stable
func SortBy[T any](slice []T, less func(a, b T) bool) {
quickSortBy(slice, 0, len(slice)-1, less)
}
// SortByField return sorted slice by field // SortByField return sorted slice by field
// slice element should be struct, field type should be int, uint, string, or bool // slice element should be struct, field type should be int, uint, string, or bool
// default sortType is ascending (asc), if descending order, set sortType to desc // default sortType is ascending (asc), if descending order, set sortType to desc
// This function is deprecated, use Sort and SortBy for replacement
func SortByField(slice any, field string, sortType ...string) error { func SortByField(slice any, field string, sortType ...string) error {
sv := sliceValue(slice) sv := sliceValue(slice)
t := sv.Type().Elem() t := sv.Type().Elem()
@@ -797,15 +816,15 @@ func SortByField(slice any, field string, sortType ...string) error {
return nil return nil
} }
// Without creates a slice excluding all given values // Without creates a slice excluding all given items
func Without[T comparable](slice []T, values ...T) []T { func Without[T comparable](slice []T, items ...T) []T {
if len(values) == 0 || len(slice) == 0 { if len(items) == 0 || len(slice) == 0 {
return slice return slice
} }
result := make([]T, 0, len(slice)) result := make([]T, 0, len(slice))
for _, v := range slice { for _, v := range slice {
if !Contain(values, v) { if !Contain(items, v) {
result = append(result, v) result = append(result, v)
} }
} }
@@ -813,11 +832,10 @@ func Without[T comparable](slice []T, values ...T) []T {
return result return result
} }
// IndexOf returns the index at which the first occurrence of a value is found in a slice or return -1 // IndexOf returns the index at which the first occurrence of a item is found in a slice or return -1 if the item cannot be found.
// if the value cannot be found. func IndexOf[T comparable](slice []T, item T) int {
func IndexOf[T comparable](slice []T, value T) int {
for i, v := range slice { for i, v := range slice {
if v == value { if v == item {
return i return i
} }
} }
@@ -825,11 +843,10 @@ func IndexOf[T comparable](slice []T, value T) int {
return -1 return -1
} }
// LastIndexOf returns the index at which the last occurrence of a value is found in a slice or return -1 // LastIndexOf returns the index at which the last occurrence of the item is found in a slice or return -1 if the then cannot be found.
// if the value cannot be found. func LastIndexOf[T comparable](slice []T, item T) int {
func LastIndexOf[T comparable](slice []T, value T) int {
for i := len(slice) - 1; i > 0; i-- { for i := len(slice) - 1; i > 0; i-- {
if value == slice[i] { if item == slice[i] {
return i return i
} }
} }
@@ -838,27 +855,27 @@ func LastIndexOf[T comparable](slice []T, value T) int {
} }
// ToSlicePointer returns a pointer to the slices of a variable parameter transformation // ToSlicePointer returns a pointer to the slices of a variable parameter transformation
func ToSlicePointer[T any](value ...T) []*T { func ToSlicePointer[T any](items ...T) []*T {
result := make([]*T, len(value)) result := make([]*T, len(items))
for i := range value { for i := range items {
result[i] = &value[i] result[i] = &items[i]
} }
return result return result
} }
// ToSlice returns a slices of a variable parameter transformation // ToSlice returns a slices of a variable parameter transformation
func ToSlice[T any](value ...T) []T { func ToSlice[T any](items ...T) []T {
result := make([]T, len(value)) result := make([]T, len(items))
copy(result, value) copy(result, items)
return result return result
} }
// AppendIfAbsent only absent append the value // AppendIfAbsent only absent append the item
func AppendIfAbsent[T comparable](slice []T, value T) []T { func AppendIfAbsent[T comparable](slice []T, item T) []T {
if !Contain(slice, value) { if !Contain(slice, item) {
slice = append(slice, value) slice = append(slice, item)
} }
return slice return slice
} }

View File

@@ -29,14 +29,14 @@ func sliceElemType(reflectType reflect.Type) reflect.Type {
func quickSort[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int, order string) { func quickSort[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int, order string) {
if lowIndex < highIndex { if lowIndex < highIndex {
p := partition(slice, lowIndex, highIndex, order) p := partitionOrderedSlice(slice, lowIndex, highIndex, order)
quickSort(slice, lowIndex, p-1, order) quickSort(slice, lowIndex, p-1, order)
quickSort(slice, p+1, highIndex, order) quickSort(slice, p+1, highIndex, order)
} }
} }
// partition split slice into two parts for quick sort // partitionOrderedSlice split ordered slice into two parts for quick sort
func partition[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int, order string) int { func partitionOrderedSlice[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int, order string) int {
p := slice[highIndex] p := slice[highIndex]
i := lowIndex i := lowIndex
@@ -59,6 +59,32 @@ func partition[T lancetconstraints.Ordered](slice []T, lowIndex, highIndex int,
return i return i
} }
func quickSortBy[T any](slice []T, lowIndex, highIndex int, less func(a, b T) bool) {
if lowIndex < highIndex {
p := partitionAnySlice(slice, lowIndex, highIndex, less)
quickSortBy(slice, lowIndex, p-1, less)
quickSortBy(slice, p+1, highIndex, less)
}
}
// partitionAnySlice split any slice into two parts for quick sort
func partitionAnySlice[T any](slice []T, lowIndex, highIndex int, less func(a, b T) bool) int {
p := slice[highIndex]
i := lowIndex
for j := lowIndex; j < highIndex; j++ {
if less(slice[j], p) {
swap(slice, i, j)
i++
}
}
swap(slice, i, highIndex)
return i
}
// swap two slice value at index i and j // swap two slice value at index i and j
func swap[T any](slice []T, i, j int) { func swap[T any](slice []T, i, j int) {
slice[i], slice[j] = slice[j], slice[i] slice[i], slice[j] = slice[j], slice[i]

View File

@@ -193,13 +193,22 @@ func TestGroupWith(t *testing.T) {
} }
func TestCount(t *testing.T) { func TestCount(t *testing.T) {
numbers := []int{1, 2, 3, 3, 5, 6}
assert := internal.NewAssert(t, "TestCountBy")
assert.Equal(1, Count(numbers, 1))
assert.Equal(2, Count(numbers, 3))
}
func TestCountBy(t *testing.T) {
nums := []int{1, 2, 3, 4, 5, 6} nums := []int{1, 2, 3, 4, 5, 6}
evenFunc := func(i, num int) bool { evenFunc := func(i, num int) bool {
return (num % 2) == 0 return (num % 2) == 0
} }
assert := internal.NewAssert(t, "TestCount") assert := internal.NewAssert(t, "TestCountBy")
assert.Equal(3, Count(nums, evenFunc)) assert.Equal(3, CountBy(nums, evenFunc))
} }
func TestFind(t *testing.T) { func TestFind(t *testing.T) {
@@ -558,6 +567,36 @@ func TestSort(t *testing.T) {
assert.Equal([]string{"e", "d", "c", "b", "a"}, strings) assert.Equal([]string{"e", "d", "c", "b", "a"}, strings)
} }
func TestSortBy(t *testing.T) {
assert := internal.NewAssert(t, "TestSortBy")
numbers := []int{1, 4, 3, 2, 5}
SortBy(numbers, func(a, b int) bool {
return a < b
})
assert.Equal([]int{1, 2, 3, 4, 5}, numbers)
type User struct {
Name string
Age uint
}
users := []User{
{Name: "a", Age: 21},
{Name: "b", Age: 15},
{Name: "c", Age: 100}}
SortBy(users, func(a, b User) bool {
return a.Age < b.Age
})
t.Logf("sort users by age: %v", users)
// output
// [{b 15} {a 21} {c 100}]
}
func TestSortByFielDesc(t *testing.T) { func TestSortByFielDesc(t *testing.T) {
assert := internal.NewAssert(t, "TestSortByFielDesc") assert := internal.NewAssert(t, "TestSortByFielDesc")