feat: 完善 stream 包对于 []string 的操作

This commit is contained in:
kercylan98 2024-02-05 11:23:12 +08:00
parent 590d0a1887
commit a2695f4fcf
4 changed files with 166 additions and 100 deletions

View File

@ -15,7 +15,7 @@ type String[S ~string] struct {
str S
}
// Elem 返回字符串
// Elem 返回原始元素
func (s *String[S]) Elem() S {
return s.str
}
@ -287,7 +287,7 @@ func (s *String[S]) Update(f func(S) S) *String[S] {
}
// Split 返回字符串切片
func (s *String[S]) Split(sep string) Strings[S] {
func (s *String[S]) Split(sep string) *Strings[S] {
slice := strings.Split(string(s.str), sep)
rep := make([]S, len(slice))
for i, v := range slice {
@ -297,7 +297,7 @@ func (s *String[S]) Split(sep string) Strings[S] {
}
// SplitN 返回字符串切片
func (s *String[S]) SplitN(sep string, n int) Strings[S] {
func (s *String[S]) SplitN(sep string, n int) *Strings[S] {
slice := strings.SplitN(string(s.str), sep, n)
rep := make([]S, len(slice))
for i, v := range slice {
@ -307,7 +307,7 @@ func (s *String[S]) SplitN(sep string, n int) Strings[S] {
}
// Batched 将字符串按照指定长度分组,最后一组可能小于指定长度
func (s *String[S]) Batched(size int) Strings[S] {
func (s *String[S]) Batched(size int) *Strings[S] {
var str = string(s.str)
var result = make([]S, 0, len(str)/size+1)
for len(str) >= size {

View File

@ -767,7 +767,7 @@ func TestString_Split(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewString(c.in).Split(c.sep)
for i, v := range got {
for i, v := range got.Elem() {
if v != c.want[i] {
t.Fatalf("NewString(%s).Split(%s) = %v; want %v", c.in, c.sep, got, c.want)
}
@ -791,7 +791,7 @@ func TestString_SplitN(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewString(c.in).SplitN(c.sep, c.n)
for i, v := range got {
for i, v := range got.Elem() {
if v != c.want[i] {
t.Fatalf("NewString(%s).SplitN(%s, %d) = %v; want %v", c.in, c.sep, c.n, got, c.want)
}
@ -814,7 +814,7 @@ func TestString_Batched(t *testing.T) {
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewString(c.in).Batched(c.size)
for i, v := range got {
for i, v := range got.Elem() {
if v != c.want[i] {
t.Fatalf("NewString(%s).Batched(%d) = %v; want %v", c.in, c.size, got, c.want)
}

View File

@ -1,123 +1,99 @@
package stream
import (
"sort"
)
import "strings"
// NewStrings 创建字符串切片
func NewStrings[S ~string](s ...S) Strings[S] {
var slice = make(Strings[S], len(s))
for i, v := range s {
slice[i] = v
}
return slice
func NewStrings[S ~string](s ...S) *Strings[S] {
return &Strings[S]{s}
}
// Strings 字符串切片
type Strings[S ~string] []S
type Strings[S ~string] struct {
s []S
}
// Elem 返回原始元素
func (s *Strings[S]) Elem() []S {
return s.s
}
// Len 返回切片长度
func (s *Strings[S]) Len() int {
return len(*s)
return len(s.s)
}
// Append 添加字符串
func (s *Strings[S]) Append(ss ...S) *Strings[S] {
*s = append(*s, NewStrings(ss...)...)
s.s = append(s.s, ss...)
return s
}
// Clear 清空切片
// Join 连接字符串
func (s *Strings[S]) Join(sep S) *String[S] {
var cast = make([]string, len(s.s))
for i, v := range s.s {
cast[i] = string(v)
}
return NewString(S(strings.Join(cast, string(sep))))
}
// Choice 选择字符串
func (s *Strings[S]) Choice(i int) *String[S] {
return NewString(s.s[i])
}
// Choices 选择多个字符串
func (s *Strings[S]) Choices(i ...int) *Strings[S] {
var ss = make([]S, len(i))
for j, v := range i {
ss[j] = s.s[v]
}
return NewStrings(ss...)
}
// ChoiceInRange 选择范围内的字符串
func (s *Strings[S]) ChoiceInRange(start, end int) *Strings[S] {
return NewStrings(s.s[start:end]...)
}
// Remove 移除字符串
func (s *Strings[S]) Remove(i int) *Strings[S] {
s.s = append(s.s[:i], s.s[i+1:]...)
return s
}
// Removes 移除多个字符串
func (s *Strings[S]) Removes(i ...int) *Strings[S] {
var ss = make([]S, 0, len(s.s)-len(i))
for j, v := range s.s {
for _, i := range i {
if j != i {
ss = append(ss, v)
}
}
}
s.s = ss
return s
}
// RemoveInRange 移除范围内的字符串
func (s *Strings[S]) RemoveInRange(start, end int) *Strings[S] {
s.s = append(s.s[:start], s.s[end:]...)
return s
}
// Clear 清空字符串
func (s *Strings[S]) Clear() *Strings[S] {
*s = make(Strings[S], 0)
s.s = []S{}
return s
}
// Copy 复制切片
func (s *Strings[S]) Copy() *Strings[S] {
ss := make(Strings[S], len(*s))
copy(ss, *s)
return &ss
}
// Range 返回指定范围的切片
func (s *Strings[S]) Range(start, end int) *Strings[S] {
*s = (*s)[start:end]
return s
}
// First 返回第一个元素
// First 第一个字符串
func (s *Strings[S]) First() *String[S] {
return NewString((*s)[0])
return NewString(s.s[0])
}
// Last 返回最后一个元素
// Last 最后一个字符串
func (s *Strings[S]) Last() *String[S] {
return NewString((*s)[len(*s)-1])
}
// Index 返回指定的元素
func (s *Strings[S]) Index(i int) *String[S] {
return NewString((*s)[i])
}
// Reverse 反转切片
func (s *Strings[S]) Reverse() *Strings[S] {
for i, j := 0, len(*s)-1; i < j; i, j = i+1, j-1 {
(*s)[i], (*s)[j] = (*s)[j], (*s)[i]
}
return s
}
// Desc 降序排序
func (s *Strings[S]) Desc() *Strings[S] {
sort.Slice(*s, func(i, j int) bool {
return (*s)[i] > (*s)[j]
})
return s
}
// Asc 升序排序
func (s *Strings[S]) Asc() *Strings[S] {
sort.Slice(*s, func(i, j int) bool {
return (*s)[i] < (*s)[j]
})
return s
}
// Sort 自定义排序
func (s *Strings[S]) Sort(f func(int, int) bool) *Strings[S] {
sort.Slice(*s, func(i, j int) bool {
return f(i, j)
})
return s
}
// Unique 去重
func (s *Strings[S]) Unique() *Strings[S] {
m := map[S]struct{}{}
for _, v := range *s {
m[v] = struct{}{}
}
*s = make(Strings[S], 0, len(m))
for k := range m {
*s = append(*s, k)
}
return s
}
// Delete 删除指定位置的字符串
func (s *Strings[S]) Delete(i int) *Strings[S] {
*s = append((*s)[:i], (*s)[i+1:]...)
return s
}
// Each 遍历切片
func (s *Strings[S]) Each(f func(int, S) bool) *Strings[S] {
for i, v := range *s {
if !f(i, v) {
break
}
}
return s
return NewString(s.s[len(s.s)-1])
}

View File

@ -1 +1,91 @@
package stream_test
import (
"github.com/kercylan98/minotaur/utils/stream"
"testing"
)
func TestNewStrings(t *testing.T) {
var cases = []struct {
name string
in []string
want []string
}{
{name: "empty", in: []string{}, want: []string{}},
{name: "one", in: []string{"a"}, want: []string{"a"}},
{name: "two", in: []string{"a", "b"}, want: []string{"a", "b"}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewStrings(c.in...)
if got.Len() != len(c.want) {
t.Errorf("got %v, want %v", got, c.want)
}
})
}
}
func TestStrings_Elem(t *testing.T) {
var cases = []struct {
name string
in []string
want []string
}{
{name: "empty", in: []string{}, want: []string{}},
{name: "one", in: []string{"a"}, want: []string{"a"}},
{name: "two", in: []string{"a", "b"}, want: []string{"a", "b"}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewStrings(c.in...).Elem()
if len(got) != len(c.want) {
t.Errorf("got %v, want %v", got, c.want)
}
})
}
}
func TestStrings_Len(t *testing.T) {
var cases = []struct {
name string
in []string
want int
}{
{name: "empty", in: []string{}, want: 0},
{name: "one", in: []string{"a"}, want: 1},
{name: "two", in: []string{"a", "b"}, want: 2},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewStrings(c.in...)
if got.Len() != c.want {
t.Errorf("got %v, want %v", got, c.want)
}
})
}
}
func TestStrings_Append(t *testing.T) {
var cases = []struct {
name string
in []string
append []string
want []string
}{
{name: "empty", in: []string{}, append: []string{"a"}, want: []string{"a"}},
{name: "one", in: []string{"a"}, append: []string{"b"}, want: []string{"a", "b"}},
{name: "two", in: []string{"a", "b"}, append: []string{"c"}, want: []string{"a", "b", "c"}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := stream.NewStrings(c.in...).Append(c.append...)
if got.Len() != len(c.want) {
t.Errorf("got %v, want %v", got, c.want)
}
})
}
}