1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-04 12:52:28 +08:00

feat: add IndexOf and LastIndexOf for stream

This commit is contained in:
dudaodong
2024-11-11 10:52:29 +08:00
parent de877e5278
commit f3579fc142
7 changed files with 263 additions and 62 deletions

View File

@@ -1,51 +1,51 @@
-----BEGIN rsa private key----- -----BEGIN rsa private key-----
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
-----END rsa private key----- -----END rsa private key-----

View File

@@ -1,14 +1,14 @@
-----BEGIN rsa public key----- -----BEGIN rsa public key-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm1rBCE+U+7M46S21q0yo MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3bRSY5GD7uJB3jvwqa9Z
ygTXHlhnZZ6IfQwRCK24EFQ6yBxtemHKjNuHEIQ/DlSh+B5DRX/bCHQ/m5c0yrNP ZFpN3uLIGbbPA+yiyf6tJZp3K3rmkVFfEcWqtK1EfHvd9G4rqLYJ9ZcohDZgD/Ww
iMKv9N3K4e8Wv/pBVqAsSmF2nSjxpXSraIACqrNSAig8MzUJ8pZq5d/9Le1AXNRa mqJtaaWh2/7feMPaitp50bYVilpPhaxULx+MIjQn3XXowYvr4fX7N052t4IC95tA
0aqHbw9YoLQJKACrdY4YbDi1NXU2ADImpnaSON0VJt5sdqA8OrEVOhm02DA4KEsh anPEEwZRQJOVMtibAxwI/ofUOCpTPtuK3AoErDxS18JPgjQ34yY4Jsch0de53+Sj
JXAp2pR4h3KT82Fuj0dMKB1iKAInXo8OeYwKgcjBxNZK4mPo6JT0ejYnFwhgtPaL Tk+bJpLUlnY4brm+A23FhwTlE5njrKA+Texrg52KJ8aPhLuVQBcZP1SJsxv2PZru
lUm0BpXAqI2eclvhn+LmM9Q/S1mvDCeLdNgQ8rh1+qPBXkCesskyu2hyuY3/H+Wj uD+0xfLDRrZ7BOTpun+1FBhdlxBefIfBQbBBfy7STw+ignTaO+IRIHhcqKZ+12Na
Q4PHjF++lCnuRv/GJYIgbUnLxKP4cxsB+jj7SU+ltgADZoLyNeUpQ9QxY8FNbKDx +4GAusmpSiB3LATy82h0nB0PX3hSOLYmFI61px4l/yM50E4brF1NFtd/BpoozZaj
JKnA7khtmvHjE4PKdy2e4M4mVcMheOtJdjvxhA2SEh9xnzP5G2JSHzE3877evInp gxjJaznuZXFQ1YSG0JjCeszqdzU+6dexGTr+4Lr87NfLekmUX1nZYy/E5lST65lG
QCJb+bfEG533B5Yrgm85C+sPcxrK684+Dmn+Y3wdQQNJgYgQGZDGDIRY8stWpRX9 lI4hX1nR5+nVN9ALRYByNz6oJd0IfF4dhoNlGPc1VksskeY8rPZwXITbSifAN7zv
G2dnWQfVtZLmSM5WwVPeI4wa6dxizk/ukylsgk9E5zJjZlPx8Fx2hnTsrNSARl0g EiwKreFV3t0BLKsvWRu9GdpWy+d2AmelXkNm+QaH2mPM17euMoNZVyzizrZaJkh/
CdbhGhRjHlVFjKI80z+evPXLCYn8B4CwWsg6ExBZSOAvcrN7XZFcalDCT5CqsNpb aHO/UgY1/y7sXFl4akC9hk9ILONCUn6FVI4BXMXb5kZgwDk5tWE5A159LtC579yG
Cg/7SXO87v8KL/54fKUc4qsCAwEAAQ== cnxyc9Y9NNFOGrqFqPiu6QUCAwEAAQ==
-----END rsa public key----- -----END rsa public key-----

View File

@@ -1,6 +1,6 @@
# Stream # Stream
Stream 流,该包仅验证简单 stream 实现,功能有限。 Stream流该包仅验证简单stream实现功能有限。
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -48,6 +48,8 @@ import (
- [NoneMatch](#NoneMatch) - [NoneMatch](#NoneMatch)
- [Count](#Count) - [Count](#Count)
- [ToSlice](#ToSlice) - [ToSlice](#ToSlice)
- [IndexOf](#IndexOf)
- [LastIndexOf](#LastIndexOf)
<div STYLE="page-break-after: always;"></div> <div STYLE="page-break-after: always;"></div>
@@ -938,3 +940,69 @@ func main() {
// [1 2 3] // [1 2 3]
} }
``` ```
### <span id="IndexOf">IndexOf</span>
<p>返回在stream中找到值的第一个匹配项的索引如果找不到值则返回-1。</p>
<b>函数签名:</b>
```go
func (s Stream[T]) IndexOf(target T, equal func(a, b T) bool) int
```
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/stream"
)
func main() {
s := stream.FromSlice([]int{1, 2, 3, 2})
result1 := s.IndexOf(0, func(a, b int) bool { return a == b })
result2 := s.IndexOf(2, func(a, b int) bool { return a == b })
fmt.Println(result1)
fmt.Println(result2)
// Output:
// -1
// 1
}
```
### <span id="LastIndexOf">LastIndexOf</span>
<p>返回在stream中找到值的最后一个匹配项的索引如果找不到值则返回-1。</p>
<b>函数签名:</b>
```go
func (s Stream[T]) LastIndexOf(target T, equal func(a, b T) bool) int
```
<b>示例:<span style="float:right;display:inline-block;">[运行](todo)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/stream"
)
func main() {
s := stream.FromSlice([]int{1, 2, 3, 2})
result1 := s.LastIndexOf(0, func(a, b int) bool { return a == b })
result2 := s.LastIndexOf(2, func(a, b int) bool { return a == b })
fmt.Println(result1)
fmt.Println(result2)
// Output:
// -1
// 3
}
```

View File

@@ -939,3 +939,69 @@ func main() {
// [1 2 3] // [1 2 3]
} }
``` ```
### <span id="IndexOf">IndexOf</span>
<p>Returns the index of the first occurrence of the specified element in this stream, or -1 if this stream does not contain the element.</p>
<b>Signature:</b>
```go
func (s Stream[T]) IndexOf(target T, equal func(a, b T) bool) int
```
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/stream"
)
func main() {
s := stream.FromSlice([]int{1, 2, 3, 2})
result1 := s.IndexOf(0, func(a, b int) bool { return a == b })
result2 := s.IndexOf(2, func(a, b int) bool { return a == b })
fmt.Println(result1)
fmt.Println(result2)
// Output:
// -1
// 1
}
```
### <span id="LastIndexOf">LastIndexOf</span>
<p>Returns the index of the last occurrence of the specified element in this stream, or -1 if this stream does not contain the element.</p>
<b>Signature:</b>
```go
func (s Stream[T]) LastIndexOf(target T, equal func(a, b T) bool) int
```
<b>Example:<span style="float:right;display:inline-block;">[Run](todo)</span></b>
```go
import (
"fmt"
"github.com/duke-git/lancet/v2/stream"
)
func main() {
s := stream.FromSlice([]int{1, 2, 3, 2})
result1 := s.LastIndexOf(0, func(a, b int) bool { return a == b })
result2 := s.LastIndexOf(2, func(a, b int) bool { return a == b })
fmt.Println(result1)
fmt.Println(result2)
// Output:
// -1
// 3
}
```

View File

@@ -393,6 +393,26 @@ func (s Stream[T]) Min(less func(a, b T) bool) (T, bool) {
return min, true return min, true
} }
// IndexOf returns the index of the first occurrence of the specified element in this stream, or -1 if this stream does not contain the element.
func (s Stream[T]) IndexOf(target T, equal func(a, b T) bool) int {
for i, v := range s.source {
if equal(v, target) {
return i
}
}
return -1
}
// LastIndexOf returns the index of the last occurrence of the specified element in this stream, or -1 if this stream does not contain the element.
func (s Stream[T]) LastIndexOf(target T, equal func(a, b T) bool) int {
for i := len(s.source) - 1; i >= 0; i-- {
if equal(s.source[i], target) {
return i
}
}
return -1
}
// ToSlice return the elements in the stream. // ToSlice return the elements in the stream.
// Play: https://go.dev/play/p/jI6_iZZuVFE // Play: https://go.dev/play/p/jI6_iZZuVFE
func (s Stream[T]) ToSlice() []T { func (s Stream[T]) ToSlice() []T {

View File

@@ -384,3 +384,31 @@ func ExampleStream_Count() {
// 3 // 3
// 0 // 0
} }
func ExampleStream_IndexOf() {
s := FromSlice([]int{1, 2, 3, 2})
result1 := s.IndexOf(0, func(a, b int) bool { return a == b })
result2 := s.IndexOf(2, func(a, b int) bool { return a == b })
fmt.Println(result1)
fmt.Println(result2)
// Output:
// -1
// 1
}
func ExampleStream_LastIndexOf() {
s := FromSlice([]int{1, 2, 3, 2})
result1 := s.LastIndexOf(0, func(a, b int) bool { return a == b })
result2 := s.LastIndexOf(2, func(a, b int) bool { return a == b })
fmt.Println(result1)
fmt.Println(result2)
// Output:
// -1
// 3
}

View File

@@ -381,3 +381,22 @@ func TestStream_Min(t *testing.T) {
assert.Equal(1, max) assert.Equal(1, max)
assert.Equal(true, ok) assert.Equal(true, ok)
} }
func TestStream_IndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_IndexOf")
s := FromSlice([]int{4, 2, 1, 3, 4})
assert.Equal(-1, s.IndexOf(0, func(a, b int) bool { return a == b }))
assert.Equal(0, s.IndexOf(4, func(a, b int) bool { return a == b }))
assert.Equal(3, s.IndexOf(3, func(a, b int) bool { return a == b }))
}
func TestStream_LastIndexOf(t *testing.T) {
assert := internal.NewAssert(t, "TestStream_LastIndexOf")
s := FromSlice([]int{4, 2, 1, 3, 2})
assert.Equal(-1, s.LastIndexOf(0, func(a, b int) bool { return a == b }))
assert.Equal(4, s.LastIndexOf(2, func(a, b int) bool { return a == b }))
}