Skip to content

Commit

Permalink
feat: add string conversion functions (#466)
Browse files Browse the repository at this point in the history
* feat: add string conversion functions

* fix: fix `Capitalize`, update tests

* fix: fix `Capitalize`, update tests

* update README.md

* update tests

* update `Capitalize`

* style: unify coding style
  • Loading branch information
eiixy authored Jun 27, 2024
1 parent a66bf34 commit 266436b
Show file tree
Hide file tree
Showing 5 changed files with 520 additions and 0 deletions.
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,72 @@ sub := len("hellô")

[[play](https://go.dev/play/p/tuhgW_lWY8l)]

### PascalCase

Converts string to pascal case.

```go
str := lo.PascalCase("hello_world")
// HelloWorld
```

[[play](https://go.dev/play/p/iZkdeLP9oiB)]

### CamelCase

Converts string to camel case.

```go
str := lo.CamelCase("hello_world")
// helloWorld
```

[[play](https://go.dev/play/p/dtyFB58MBRp)]

### KebabCase

Converts string to kebab case.

```go
str := lo.KebabCase("helloWorld")
// hello-world
```

[[play](https://go.dev/play/p/2YTuPafwECA)]

### SnakeCase

Converts string to snake case.

```go
str := lo.SnakeCase("HelloWorld")
// hello_world
```

[[play](https://go.dev/play/p/QVKJG9nOnDg)]

### Words

Splits string into an array of its words.

```go
str := lo.Words("helloWorld")
// []string{"hello", "world"}
```

[[play](https://go.dev/play/p/2P4zhqqq61g)]

### Capitalize

Converts the first character of string to upper case and the remaining to lower case.

```go
str := lo.PascalCase("heLLO")
// Hello
```

[[play](https://go.dev/play/p/jBIJ_OFtFYp)]

### T2 -> T9

Creates a tuple from a list of values.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/thoas/go-funk v0.9.1
go.uber.org/goleak v1.2.1
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17
golang.org/x/text v0.16.0
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
68 changes: 68 additions & 0 deletions string.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package lo

import (
"golang.org/x/text/cases"
"golang.org/x/text/language"
"math/rand"
"regexp"
"strings"
"unicode"
"unicode/utf8"
)

Expand All @@ -14,6 +18,9 @@ var (
AlphanumericCharset = append(LettersCharset, NumbersCharset...)
SpecialCharset = []rune("!@#$%^&*()_+-=[]{}|;':\",./<>?")
AllCharset = append(AlphanumericCharset, SpecialCharset...)

splitWordReg = regexp.MustCompile(`([a-z])([A-Z0-9])|([a-zA-Z])([0-9])|([0-9])([a-zA-Z])|([A-Z])([A-Z])([a-z])`)
splitNumberLetterReg = regexp.MustCompile(`([0-9])([a-zA-Z])`)
)

// RandomString return a random string.
Expand Down Expand Up @@ -94,3 +101,64 @@ func ChunkString[T ~string](str T, size int) []T {
func RuneLength(str string) int {
return utf8.RuneCountInString(str)
}

// PascalCase converts string to pascal case.
func PascalCase(str string) string {
items := Words(str)
for i, item := range items {
items[i] = Capitalize(item)
}
return strings.Join(items, "")
}

// CamelCase converts string to camel case.
func CamelCase(str string) string {
items := Words(str)
for i, item := range items {
item = strings.ToLower(item)
if i > 0 {
item = Capitalize(item)
}
items[i] = item
}
return strings.Join(items, "")
}

// KebabCase converts string to kebab case.
func KebabCase(str string) string {
items := Words(str)
for i, item := range items {
items[i] = strings.ToLower(item)
}
return strings.Join(items, "-")
}

// SnakeCase converts string to snake case.
func SnakeCase(str string) string {
items := Words(str)
for i, item := range items {
items[i] = strings.ToLower(item)
}
return strings.Join(items, "_")
}

// Words splits string into an array of its words.
func Words(str string) []string {
str = splitWordReg.ReplaceAllString(str, `$1$3$5$7 $2$4$6$8$9`)
// example: Int8Value => Int 8Value => Int 8 Value
str = splitNumberLetterReg.ReplaceAllString(str, "$1 $2")
var result strings.Builder
for _, r := range str {
if unicode.IsLetter(r) || unicode.IsDigit(r) {
result.WriteRune(r)
} else {
result.WriteRune(' ')
}
}
return strings.Fields(result.String())
}

// Capitalize converts the first character of string to upper case and the remaining to lower case.
func Capitalize(str string) string {
return cases.Title(language.English).String(str)
}
Loading

0 comments on commit 266436b

Please sign in to comment.