mirror of
https://github.com/duke-git/lancet.git
synced 2026-02-09 07:02:29 +08:00
feat: add new functions
This commit is contained in:
@@ -8,11 +8,17 @@ import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
"unsafe"
|
||||
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// used in `Shuffle` function
|
||||
var rng = rand.New(rand.NewSource(int64(time.Now().UnixNano())))
|
||||
|
||||
// CamelCase covert string to camelCase string.
|
||||
// non letters and numbers will be ignored
|
||||
// eg. "Foo-#1😄$_%^&*(1bar" => "foo11Bar"
|
||||
@@ -559,3 +565,82 @@ func HammingDistance(a, b string) (int, error) {
|
||||
|
||||
return distance, nil
|
||||
}
|
||||
|
||||
// Concat uses the strings.Builder to concatenate the input strings.
|
||||
// - `length` is the expected length of the concatenated string.
|
||||
// - if you are unsure about the length of the string to be concatenated, please pass 0 or a negative number.
|
||||
//
|
||||
// Play: todo
|
||||
func Concat(length int, str ...string) string {
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
sb := strings.Builder{}
|
||||
if length <= 0 {
|
||||
sb.Grow(len(str[0]) * len(str))
|
||||
} else {
|
||||
sb.Grow(length)
|
||||
}
|
||||
|
||||
for _, s := range str {
|
||||
sb.WriteString(s)
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// Ellipsis truncates a string to a specified length and appends an ellipsis.
|
||||
func Ellipsis(str string, length int) string {
|
||||
str = strings.TrimSpace(str)
|
||||
|
||||
if length <= 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
runes := []rune(str)
|
||||
|
||||
if len(runes) <= length {
|
||||
return str
|
||||
}
|
||||
|
||||
return string(runes[:length]) + "..."
|
||||
}
|
||||
|
||||
// Shuffle the order of characters of given string.
|
||||
func Shuffle(str string) string {
|
||||
runes := []rune(str)
|
||||
|
||||
for i := len(runes) - 1; i > 0; i-- {
|
||||
j := rng.Intn(i + 1)
|
||||
runes[i], runes[j] = runes[j], runes[i]
|
||||
}
|
||||
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
// Rotate rotates the string by the specified number of characters.
|
||||
func Rotate(str string, shift int) string {
|
||||
if shift == 0 {
|
||||
return str
|
||||
}
|
||||
|
||||
runes := []rune(str)
|
||||
length := len(runes)
|
||||
if length == 0 {
|
||||
return str
|
||||
}
|
||||
|
||||
shift = shift % length
|
||||
|
||||
if shift < 0 {
|
||||
shift = length + shift
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
sb.Grow(length)
|
||||
|
||||
sb.WriteString(string(runes[length-shift:]))
|
||||
sb.WriteString(string(runes[:length-shift]))
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
@@ -505,3 +505,79 @@ func TestSubInBetween(t *testing.T) {
|
||||
assert.Equal("", SubInBetween(str, "a", ""))
|
||||
assert.Equal("", SubInBetween(str, "a", "f"))
|
||||
}
|
||||
|
||||
func TestConcat(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestConcat")
|
||||
|
||||
assert.Equal("", Concat(0))
|
||||
assert.Equal("a", Concat(1, "a"))
|
||||
assert.Equal("ab", Concat(2, "a", "b"))
|
||||
assert.Equal("abc", Concat(3, "a", "b", "c"))
|
||||
assert.Equal("abc", Concat(3, "a", "", "b", "c", ""))
|
||||
assert.Equal("你好,世界!", Concat(0, "你好", ",", "", "世界!", ""))
|
||||
assert.Equal("Hello World!", Concat(0, "Hello", " Wo", "r", "ld!", ""))
|
||||
}
|
||||
|
||||
func TestEllipsis(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := internal.NewAssert(t, "TestEllipsis")
|
||||
|
||||
tests := []struct {
|
||||
input string
|
||||
length int
|
||||
expected string
|
||||
}{
|
||||
{"", 0, ""},
|
||||
{"hello world", 0, ""},
|
||||
{"hello world", -1, ""},
|
||||
{"hello world", 5, "hello..."},
|
||||
{"hello world", 11, "hello world"},
|
||||
{"你好,世界!", 2, "你好..."},
|
||||
{"😀😃😄😁😆", 3, "😀😃😄..."},
|
||||
{"This is a test.", 10, "This is a ..."},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
assert.Equal(tt.expected, Ellipsis(tt.input, tt.length))
|
||||
}
|
||||
}
|
||||
|
||||
func TestShuffle(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestShuffle")
|
||||
|
||||
assert.Equal("", Shuffle(""))
|
||||
assert.Equal("a", Shuffle("a"))
|
||||
|
||||
str := "hello"
|
||||
shuffledStr := Shuffle(str)
|
||||
assert.Equal(5, len(shuffledStr))
|
||||
}
|
||||
|
||||
func TestRotate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestRotate")
|
||||
|
||||
tests := []struct {
|
||||
input string
|
||||
shift int
|
||||
expected string
|
||||
}{
|
||||
{"", 1, ""},
|
||||
{"a", 0, "a"},
|
||||
{"a", 1, "a"},
|
||||
{"a", -1, "a"},
|
||||
|
||||
{"Hello", -2, "lloHe"},
|
||||
{"Hello", 1, "oHell"},
|
||||
{"Hello, world!", 3, "ld!Hello, wor"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
assert.Equal(tt.expected, Rotate(tt.input, tt.shift))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user