feat: 完善 stream 包对于 []string 的操作
This commit is contained in:
parent
590d0a1887
commit
a2695f4fcf
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 清空切片
|
||||
func (s *Strings[S]) Clear() *Strings[S] {
|
||||
*s = make(Strings[S], 0)
|
||||
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 返回第一个元素
|
||||
func (s *Strings[S]) First() *String[S] {
|
||||
return NewString((*s)[0])
|
||||
}
|
||||
|
||||
// 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]
|
||||
// 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 s
|
||||
return NewString(S(strings.Join(cast, string(sep))))
|
||||
}
|
||||
|
||||
// Desc 降序排序
|
||||
func (s *Strings[S]) Desc() *Strings[S] {
|
||||
sort.Slice(*s, func(i, j int) bool {
|
||||
return (*s)[i] > (*s)[j]
|
||||
})
|
||||
return s
|
||||
// Choice 选择字符串
|
||||
func (s *Strings[S]) Choice(i int) *String[S] {
|
||||
return NewString(s.s[i])
|
||||
}
|
||||
|
||||
// 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)
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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.s = []S{}
|
||||
return s
|
||||
}
|
||||
|
||||
// First 第一个字符串
|
||||
func (s *Strings[S]) First() *String[S] {
|
||||
return NewString(s.s[0])
|
||||
}
|
||||
|
||||
// Last 最后一个字符串
|
||||
func (s *Strings[S]) Last() *String[S] {
|
||||
return NewString(s.s[len(s.s)-1])
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue