mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-09 07:02:29 +08:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b697858038 | ||
|
|
5446f7e33c | ||
|
|
553f63e76b | ||
|
|
fc3e94df58 | ||
|
|
5c66f38a5b | ||
|
|
70e213b3f7 | ||
|
|
c1b7500bcb | ||
|
|
3d7600a9e4 | ||
|
|
0299c454ab | ||
|
|
741af66404 | ||
|
|
ef5d0379a1 | ||
|
|
105ab49763 | ||
|
|
b5ba9ba573 | ||
|
|
ac3baac5c6 | ||
|
|
a82b5dd206 |
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -35,7 +35,7 @@ English | [简体中文](./README_zh-CN.md)
|
||||
go get github.com/duke-git/lancet/v2 // will install latest version of v2.x.x
|
||||
```
|
||||
|
||||
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.3.0. </b>
|
||||
2. <b>For users who use version below go1.18, you should install v1.x.x. now latest v1 is v1.3.1. </b>
|
||||
```go
|
||||
go get github.com/duke-git/lancet@v1.3.0 // below go1.18, install latest version of v1.x.x
|
||||
```
|
||||
@@ -371,6 +371,7 @@ import "github.com/duke-git/lancet/v2/slice"
|
||||
```
|
||||
|
||||
#### Function list:
|
||||
- [AppendIfAbsent](https://github.com/duke-git/lancet/blob/main/docs/slice.md#AppendIfAbsent)
|
||||
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Contain)
|
||||
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice.md#ContainSubSlice)
|
||||
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice.md#Chunk)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<br/>
|
||||
|
||||

|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://github.com/duke-git/lancet/releases)
|
||||
[](https://pkg.go.dev/github.com/duke-git/lancet/v2)
|
||||
[](https://goreportcard.com/report/github.com/duke-git/lancet/v2)
|
||||
[](https://github.com/duke-git/lancet/actions/workflows/codecov.yml)
|
||||
@@ -35,7 +35,7 @@
|
||||
go get github.com/duke-git/lancet/v2 //安装v2最新版本v2.x.x
|
||||
```
|
||||
|
||||
2. <b>使用go1.18以下版本的用户,必须安装v1.x.x。目前最新的v1版本是v1.3.0。</b>
|
||||
2. <b>使用go1.18以下版本的用户,必须安装v1.x.x。目前最新的v1版本是v1.3.1。</b>
|
||||
```go
|
||||
go get github.com/duke-git/lancet@v1.3.0 // 使用go1.18以下版本, 必须安装v1.x.x版本
|
||||
```
|
||||
@@ -367,6 +367,7 @@ import "github.com/duke-git/lancet/v2/slice"
|
||||
```
|
||||
|
||||
#### 函数列表:
|
||||
- [AppendIfAbsent](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#AppendIfAbsent)
|
||||
- [Contain](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Contain)
|
||||
- [ContainSubSlice](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#ContainSubSlice)
|
||||
- [Chunk](https://github.com/duke-git/lancet/blob/main/docs/slice_zh-CN.md#Chunk)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/duke-git/lancet/v2/internal"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
func TestToChar(t *testing.T) {
|
||||
@@ -204,7 +205,10 @@ func TestMapToSlice(t *testing.T) {
|
||||
return key + ":" + strconv.Itoa(value)
|
||||
})
|
||||
|
||||
assert.Equal([]string{"a:1", "b:2", "c:3"}, result)
|
||||
assert.Equal(3, len(result))
|
||||
assert.Equal(true, slice.Contain(result, "a:1"))
|
||||
assert.Equal(true, slice.Contain(result, "b:2"))
|
||||
assert.Equal(true, slice.Contain(result, "c:3"))
|
||||
}
|
||||
|
||||
func TestColorHexToRGB(t *testing.T) {
|
||||
|
||||
@@ -31,7 +31,7 @@ func (l *List[T]) ValueOf(index int) (*T, bool) {
|
||||
return &l.data[index], true
|
||||
}
|
||||
|
||||
// IndexOf reture the index of value. if not found return -1
|
||||
// IndexOf returns the index of value. if not found return -1
|
||||
func (l *List[T]) IndexOf(value T) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
@@ -44,6 +44,48 @@ func (l *List[T]) IndexOf(value T) int {
|
||||
return index
|
||||
}
|
||||
|
||||
// LastIndexOf returns the index of the last occurrence of the value in this list.
|
||||
// if not found return -1
|
||||
func (l *List[T]) LastIndexOf(value T) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
for i := len(data) - 1; i >= 0; i-- {
|
||||
if reflect.DeepEqual(data[i], value) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// IndexOfFunc returns the first index satisfying f(v)
|
||||
// if not found return -1
|
||||
func (l *List[T]) IndexOfFunc(f func(T) bool) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
for i, v := range data {
|
||||
if f(v) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying f(data[i])
|
||||
// if not found return -1
|
||||
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int {
|
||||
index := -1
|
||||
data := l.data
|
||||
for i := len(data) - 1; i >= 0; i-- {
|
||||
if f(data[i]) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
// Contain checks if the value in the list or not
|
||||
func (l *List[T]) Contain(value T) bool {
|
||||
data := l.data
|
||||
@@ -121,6 +163,31 @@ func (l *List[T]) DeleteAt(index int) {
|
||||
l.data = data
|
||||
}
|
||||
|
||||
// DeleteIf delete all satisfying f(data[i]), returns count of removed elements
|
||||
func (l *List[T]) DeleteIf(f func(T) bool) int {
|
||||
data := l.data
|
||||
size := len(data)
|
||||
|
||||
var c int
|
||||
for index := 0; index < len(data); index++ {
|
||||
if !f(data[index]) {
|
||||
continue
|
||||
}
|
||||
if index == size-1 {
|
||||
data = append(data[:index])
|
||||
} else {
|
||||
data = append(data[:index], data[index+1:]...)
|
||||
index--
|
||||
}
|
||||
c++
|
||||
}
|
||||
|
||||
if c > 0 {
|
||||
l.data = data
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// UpdateAt update value of list at index, index shoud between 0 and list size -1
|
||||
func (l *List[T]) UpdateAt(index int, value T) {
|
||||
data := l.data
|
||||
@@ -181,6 +248,11 @@ func (l *List[T]) Size() int {
|
||||
return len(l.data)
|
||||
}
|
||||
|
||||
// Cap return cap of the inner data
|
||||
func (l *List[T]) Cap() int {
|
||||
return cap(l.data)
|
||||
}
|
||||
|
||||
// Swap the value of index i and j in list
|
||||
func (l *List[T]) Swap(i, j int) {
|
||||
size := len(l.data)
|
||||
@@ -243,3 +315,11 @@ func (l *List[T]) Intersection(other *List[T]) *List[T] {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.
|
||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T] {
|
||||
data := l.data[fromIndex:toIndex]
|
||||
subList := make([]T, len(data))
|
||||
copy(subList, data)
|
||||
return NewList(subList)
|
||||
}
|
||||
|
||||
@@ -36,6 +36,51 @@ func TestIndexOf(t *testing.T) {
|
||||
assert.Equal(-1, i)
|
||||
}
|
||||
|
||||
func TestIndexOfFunc(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIndexOf")
|
||||
|
||||
list := NewList([]int{1, 2, 3})
|
||||
i := list.IndexOfFunc(func(a int) bool { return a == 1 })
|
||||
assert.Equal(0, i)
|
||||
|
||||
i = list.IndexOfFunc(func(a int) bool { return a == 4 })
|
||||
assert.Equal(-1, i)
|
||||
}
|
||||
|
||||
func TestLastIndexOf(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIndexOf")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 3, 3, 3, 4, 5, 6, 9})
|
||||
i := list.LastIndexOf(3)
|
||||
assert.Equal(5, i)
|
||||
|
||||
i = list.LastIndexOf(10)
|
||||
assert.Equal(-1, i)
|
||||
|
||||
i = list.LastIndexOf(4)
|
||||
assert.Equal(6, i)
|
||||
|
||||
i = list.LastIndexOf(1)
|
||||
assert.Equal(0, i)
|
||||
}
|
||||
|
||||
func TestLastIndexOfFunc(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestIndexOf")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 3, 3, 3, 4, 5, 6, 9})
|
||||
i := list.LastIndexOfFunc(func(a int) bool { return a == 3 })
|
||||
assert.Equal(5, i)
|
||||
|
||||
i = list.LastIndexOfFunc(func(a int) bool { return a == 10 })
|
||||
assert.Equal(-1, i)
|
||||
|
||||
i = list.LastIndexOfFunc(func(a int) bool { return a == 4 })
|
||||
assert.Equal(6, i)
|
||||
|
||||
i = list.LastIndexOfFunc(func(a int) bool { return a == 1 })
|
||||
assert.Equal(0, i)
|
||||
}
|
||||
|
||||
func TestContain(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestContain")
|
||||
|
||||
@@ -216,6 +261,18 @@ func TestSize(t *testing.T) {
|
||||
assert.Equal(0, empty.Size())
|
||||
}
|
||||
|
||||
func TestCap(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestCap")
|
||||
|
||||
data := make([]int, 0, 100)
|
||||
list := NewList(data)
|
||||
assert.Equal(100, list.Cap())
|
||||
|
||||
data = make([]int, 0)
|
||||
list = NewList(data)
|
||||
assert.Equal(0, list.Cap())
|
||||
}
|
||||
|
||||
func TestSwap(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSwap")
|
||||
|
||||
@@ -270,3 +327,33 @@ func TestIntersection(t *testing.T) {
|
||||
list3 := list1.Intersection(list2)
|
||||
assert.Equal(true, expected.Equal(list3))
|
||||
}
|
||||
|
||||
func TestSubSlice(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSubSlice")
|
||||
|
||||
list := NewList([]int{1, 2, 3, 4, 5, 8})
|
||||
subList := list.SubList(2, 5)
|
||||
|
||||
assert.Equal([]int{3, 4, 5}, subList.Data())
|
||||
}
|
||||
|
||||
func BenchmarkSubSlice(b *testing.B) {
|
||||
list := NewList([]int{1, 2, 3, 4, 5, 8})
|
||||
for n := 0; n < b.N; n++ {
|
||||
list.SubList(2, 5)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteIf(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestDeleteIf")
|
||||
|
||||
list := NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
|
||||
count := list.DeleteIf(func(a int) bool { return a == 1 })
|
||||
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||
assert.Equal(12, count)
|
||||
|
||||
count = list.DeleteIf(func(a int) bool { return a == 5 })
|
||||
assert.Equal([]int{2, 3, 4}, list.Data())
|
||||
assert.Equal(0, count)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ import (
|
||||
- [Data](#Data)
|
||||
- [ValueOf](#ValueOf)
|
||||
- [IndexOf](#IndexOf)
|
||||
- [LastIndexOf](#LastIndexOf)
|
||||
- [IndexOfFunc](#IndexOfFunc)
|
||||
- [LastIndexOfFunc](#LastIndexOfFunc)
|
||||
- [Push](#Push)
|
||||
- [PopFirst](#PopFirst)
|
||||
- [PopLast](#PopLast)
|
||||
@@ -38,11 +41,14 @@ import (
|
||||
- [Clone](#Clone)
|
||||
- [Merge](#Merge)
|
||||
- [Size](#Size)
|
||||
- [Cap](#Cap)
|
||||
- [Swap](#Swap)
|
||||
- [Reverse](#Reverse)
|
||||
- [Unique](#Unique)
|
||||
- [Union](#Union)
|
||||
- [Intersection](#Intersection)
|
||||
- [SubList](#SubList)
|
||||
- [DeleteIf](#DeleteIf)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -167,7 +173,7 @@ func main() {
|
||||
|
||||
|
||||
### <span id="IndexOf">IndexOf</span>
|
||||
<p>Reture the index of value in the list. if not found return -1</p>
|
||||
<p>Returns the index of value in the list. if not found return -1</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
@@ -192,6 +198,84 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LastIndexOf">LastIndexOf</span>
|
||||
<p> Returns the index of the last occurrence of the value in this list if not found return -1</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) LastIndexOf(value T) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
li := list.NewList([]int{1, 2, 3, 1})
|
||||
|
||||
fmt.Println(li.LastIndexOf(1)) // 3
|
||||
fmt.Println(li.LastIndexOf(0)) //-1
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IndexOfFunc">IndexOfFunc</span>
|
||||
<p> IndexOfFunc returns the first index satisfying f(v). if not found return -1</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) IndexOfFunc(f func(T) bool) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
li := list.NewList([]int{1, 2, 3})
|
||||
|
||||
fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 1 })) //0
|
||||
fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LastIndexOfFunc">LastIndexOfFunc</span>
|
||||
<p>LastIndexOfFunc returns the index of the last occurrence of the value in this list satisfying f(data[i]). if not found return -1</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
li := list.NewList([]int{1, 2, 3, 1})
|
||||
|
||||
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3
|
||||
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Push">Push</span>
|
||||
@@ -568,6 +652,36 @@ func main() {
|
||||
|
||||
|
||||
|
||||
### <span id="Cap">Cap</span>
|
||||
<p>Cap return cap of the inner data</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) Cap() int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := make([]int, 0, 100)
|
||||
|
||||
li := list.NewList(data)
|
||||
|
||||
fmt.Println(li.Cap()) // 100
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="Swap">Swap</span>
|
||||
<p>Swap the value at two index in list</p>
|
||||
|
||||
@@ -710,4 +824,61 @@ func main() {
|
||||
|
||||
fmt.Println(li3.Data()) //4
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="SubList">SubList</span>
|
||||
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l := list.NewList([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
fmt.Println(l.SubList(2, 5)) // []int{3, 4, 5}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="DeleteIf">DeleteIf</span>
|
||||
<p>DeleteIf delete all satisfying f(data[i]), returns count of removed elements</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) DeleteIf(f func(T) bool) int
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
|
||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -26,11 +26,15 @@ import (
|
||||
- [Data](#Data)
|
||||
- [ValueOf](#ValueOf)
|
||||
- [IndexOf](#IndexOf)
|
||||
- [LastIndexOf](#LastIndexOf)
|
||||
- [IndexOfFunc](#IndexOfFunc)
|
||||
- [LastIndexOfFunc](#LastIndexOfFunc)
|
||||
- [Push](#Push)
|
||||
- [PopFirst](#PopFirst)
|
||||
- [PopLast](#PopLast)
|
||||
- [DeleteAt](#DeleteAt)
|
||||
- [InsertAt](#InsertAt)
|
||||
|
||||
- [UpdateAt](#UpdateAt)
|
||||
- [Equal](#Equal)
|
||||
- [IsEmpty](#IsEmpty)
|
||||
@@ -38,11 +42,14 @@ import (
|
||||
- [Clone](#Clone)
|
||||
- [Merge](#Merge)
|
||||
- [Size](#Size)
|
||||
- [Cap](#Cap)
|
||||
- [Swap](#Swap)
|
||||
- [Reverse](#Reverse)
|
||||
- [Unique](#Unique)
|
||||
- [Union](#Union)
|
||||
- [Intersection](#Intersection)
|
||||
- [SubList](#SubList)
|
||||
- [DeleteIf](#DeleteIf)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -192,6 +199,85 @@ func main() {
|
||||
```
|
||||
|
||||
|
||||
### <span id="LastIndexOf">LastIndexOf</span>
|
||||
<p>返回列表中最后一次出现的值的索引。如果未找到,则返回-1</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) LastIndexOf(value T) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
li := list.NewList([]int{1, 2, 3, 1})
|
||||
|
||||
fmt.Println(li.LastIndexOf(1)) // 3
|
||||
fmt.Println(li.LastIndexOf(0)) //-1
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="IndexOfFunc">IndexOfFunc</span>
|
||||
<p>返回第一个符合函数条件的元素的索引。如果未找到,则返回-1</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) IndexOfFunc(f func(T) bool) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
li := list.NewList([]int{1, 2, 3})
|
||||
|
||||
fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 1 })) //0
|
||||
fmt.Println(li.IndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||
}
|
||||
```
|
||||
|
||||
### <span id="LastIndexOfFunc">LastIndexOfFunc</span>
|
||||
<p>返回最后一个符合函数条件的元素的索引。如果未找到,则返回-1</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) LastIndexOfFunc(f func(T) bool) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
li := list.NewList([]int{1, 2, 3, 1})
|
||||
|
||||
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 1 })) // 3
|
||||
fmt.Println(li.LastIndexOfFunc(func(a int) bool { return a == 0 })) //-1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Push">Push</span>
|
||||
<p>将值附加到列表末尾</p>
|
||||
@@ -566,6 +652,34 @@ func main() {
|
||||
|
||||
|
||||
|
||||
### <span id="Cap">Cap</span>
|
||||
<p>返回列表数据容量</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) Cap() int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
data := make([]int, 0, 100)
|
||||
|
||||
li := list.NewList(data)
|
||||
|
||||
fmt.Println(li.Cap()) // 100
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Swap">Swap</span>
|
||||
<p>交换列表中两个索引位置的值</p>
|
||||
@@ -709,4 +823,60 @@ func main() {
|
||||
|
||||
fmt.Println(li3.Data()) //4
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="SubList">SubList</span>
|
||||
<p>SubList returns a sub list of the original list between the specified fromIndex, inclusive, and toIndex, exclusive.</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) SubList(fromIndex, toIndex int) *List[T]
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l := list.NewList([]int{1, 2, 3, 4, 5, 6})
|
||||
|
||||
fmt.Println(l.SubList(2, 5)) // []int{3, 4, 5}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
### <span id="DeleteIf">DeleteIf</span>
|
||||
<p>删除列表中所有符合函数(调用函数返回true)的元素,返回删除元素的数量</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func (l *List[T]) DeleteIf(f func(T) bool) int
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
list "github.com/duke-git/lancet/v2/datastructure/list"
|
||||
)
|
||||
|
||||
func main() {
|
||||
l := list.NewList([]int{1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1})
|
||||
|
||||
fmt.Println(l.DeleteIf(func(a int) bool { return a == 1 })) // 12
|
||||
fmt.Println(l.Data()) // []int{2, 3, 4}
|
||||
}
|
||||
```
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
- [Merge](#Merge)
|
||||
- [Minus](#Minus)
|
||||
- [Values](#Values)
|
||||
- [Values](#Values)
|
||||
- [IsDisjoint](#IsDisjoint)
|
||||
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
@@ -305,7 +305,7 @@ func main() {
|
||||
```
|
||||
|
||||
### <span id="IsDisjoint">IsDisjoint</span>
|
||||
<p>Checks two are disjoint if they have no keys in common</p>
|
||||
<p>Checks two maps are disjoint if they have no keys in common</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## Index
|
||||
- [AppendIfAbsent](#AppendIfAbsent)
|
||||
- [Contain](#Contain)
|
||||
- [ContainSubSlice](#ContainSubSlice)
|
||||
- [Chunk](#Chunk)
|
||||
@@ -69,6 +70,33 @@ import (
|
||||
|
||||
## Documentation
|
||||
|
||||
### <span id="AppendIfAbsent">AppendIfAbsent</span>
|
||||
<p>If slice doesn't contain the value, append it to the slice.</p>
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```go
|
||||
func AppendIfAbsent[T comparable](slice []T, value T) []T
|
||||
```
|
||||
<b>Example:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
strs := []string{"a", "b"}
|
||||
res1 := slice.AppendIfAbsent(strs, "a")
|
||||
fmt.Println(res1) //[]string{"a", "b"}
|
||||
|
||||
res2 := slice.AppendIfAbsent(strs, "cannot")
|
||||
fmt.Println(res2"}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### <span id="Contain">Contain</span>
|
||||
<p>Check if the value is in the slice or not.</p>
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
<div STYLE="page-break-after: always;"></div>
|
||||
|
||||
## 目录
|
||||
- [AppendIfAbsent](#AppendIfAbsent)
|
||||
- [Contain](#Contain)
|
||||
- [ContainSubSlice](#ContainSubSlice)
|
||||
- [Chunk](#Chunk)
|
||||
@@ -69,6 +70,34 @@ import (
|
||||
|
||||
## 文档
|
||||
|
||||
### <span id="AppendIfAbsent">AppendIfAbsent</span>
|
||||
<p>当前切片中不包含值时,将该值追加到切片中</p>
|
||||
|
||||
<b>函数签名:</b>
|
||||
|
||||
```go
|
||||
func AppendIfAbsent[T comparable](slice []T, value T) []T
|
||||
```
|
||||
<b>例子:</b>
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/duke-git/lancet/v2/slice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
strs := []string{"a", "b"}
|
||||
res1 := slice.AppendIfAbsent(strs, "a")
|
||||
fmt.Println(res1) //[]string{"a", "b"}
|
||||
|
||||
res2 := slice.AppendIfAbsent(strs, "cannot")
|
||||
fmt.Println(res2"}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### <span id="Contain">Contain</span>
|
||||
<p>判断slice是否包含value</p>
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ func TestDebounced(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSchedule(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestSchedule")
|
||||
// assert := internal.NewAssert(t, "TestSchedule")
|
||||
|
||||
var res []string
|
||||
appendStr := func(s string) {
|
||||
@@ -127,6 +127,10 @@ func TestSchedule(t *testing.T) {
|
||||
time.Sleep(5 * time.Second)
|
||||
close(stop)
|
||||
|
||||
expected := []string{"*", "*", "*", "*", "*"}
|
||||
assert.Equal(expected, res)
|
||||
t.Log(res)
|
||||
|
||||
// todo: in github action, for now, this test is not working sometimes
|
||||
// res maybe [* * * * *] or [* * * * * *]
|
||||
// expected := []string{"*", "*", "*", "*", "*"}
|
||||
// assert.Equal(expected, res)
|
||||
}
|
||||
|
||||
@@ -14,13 +14,13 @@ import (
|
||||
|
||||
// Contain check if the value is in the slice or not
|
||||
func Contain[T comparable](slice []T, value T) bool {
|
||||
set := make(map[T]struct{}, len(slice))
|
||||
for _, v := range slice {
|
||||
if v == value {
|
||||
return true
|
||||
}
|
||||
set[v] = struct{}{}
|
||||
}
|
||||
|
||||
return false
|
||||
_, ok := set[value]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ContainSubSlice check if the slice contain subslice or not
|
||||
@@ -851,3 +851,11 @@ func ToSlice[T any](value ...T) []T {
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// AppendIfAbsent only absent append the value
|
||||
func AppendIfAbsent[T comparable](slice []T, value T) []T {
|
||||
if !Contain(slice, value) {
|
||||
slice = append(slice, value)
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
||||
@@ -609,3 +609,11 @@ func TestToSlicePointer(t *testing.T) {
|
||||
assert.Equal([]*string{&str1}, ToSlicePointer(str1))
|
||||
assert.Equal([]*string{&str1, &str2}, ToSlicePointer(str1, str2))
|
||||
}
|
||||
|
||||
func TestAppendIfAbsent(t *testing.T) {
|
||||
assert := internal.NewAssert(t, "TestAppendIfAbsent")
|
||||
|
||||
str1 := []string{"a", "b"}
|
||||
assert.Equal([]string{"a", "b"}, AppendIfAbsent(str1, "a"))
|
||||
assert.Equal([]string{"a", "b", "c"}, AppendIfAbsent(str1, "c"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user