Skip to content
This repository was archived by the owner on May 23, 2022. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@

# Dependency directories
vendor

# IDE Files
.idea/
234 changes: 233 additions & 1 deletion str/str.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package str

import "unicode"
import (
"strings"
"unicode"
)

func UpperFirst(input string) string {
if len(input) == 0 {
Expand All @@ -19,3 +22,232 @@ func InSlice(input interface{}, expects ...interface{}) bool {
}
return false
}

// Return the remainder of a string after the first occurrence of a given value.
func After(subject string, search string) string {
Copy link
Collaborator

@octoper octoper Apr 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be reduced to

func After(subject string, search string) string {
	if len(search) == 0 {
		return input
	}
	results := strings.SplitN(subject, search, 2)
	return results[len(results)-1]
}

l := len(search)
if l == 0 {
return ""
}

byteIndex := strings.Index(subject, search)
if byteIndex == -1 {
return subject
}

byteSubject := []byte(subject)
byteSearch := []byte(search)

result := string(byteSubject[byteIndex+ len(byteSearch):])
return result
}

// Return the remainder of a string after the last occurrence of a given value.
func AfterLast(subject string, search string) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code can be reduced to

func AfterLast(subject string, search string) string {
	if len(search) == 0 {
		return subject
	}
	position := strings.LastIndex(subject, search)

	if position == -1 {
		return subject
	}

	return subject[position+len(search):]
}

l := len(search)
if l == 0 {
return ""
}

byteIndex := strings.LastIndex(subject, search)
if byteIndex == -1 {
return subject
}

byteSubject := []byte(subject)
byteSearch := []byte(search)

result := string(byteSubject[byteIndex+ len(byteSearch):])
return result
}

// Get the portion of a string before the first occurrence of a given value.
func Before(subject string, search string) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code can be reduced to

func Before(subject string, search string) string {
	if len(search) == 0 {
		return subject
	}
	position := strings.Index(subject, search)

	if position == -1 {
		return subject
	}

	return subject[:position]
}

l := len(search)
if l == 0 {
return subject
}

byteIndex := strings.Index(subject, search)
if byteIndex == -1 {
return subject
}

byteSubject := []byte(subject)

result := string(byteSubject[:byteIndex])
return result
}

func BeforeLast(subject string, search string) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code can be reduced to

func BeforeLast(subject string, search string) string {
	if len(search) == 0 {
		return subject
	}
	position := strings.LastIndex(subject, search)

	if position == -1 {
		return subject
	}

	return subject[:position]
}

l := len(search)
if l == 0 {
return subject
}

byteIndex := strings.LastIndex(subject, search)
if byteIndex == -1 {
return subject
}

byteSubject := []byte(subject)

result := string(byteSubject[:byteIndex])
return result
}

func Between(subject string, from string, to string) string {
if len(from) == 0 || len(to) == 0 {
return subject
}
return BeforeLast(After(subject, from), to)
}

func Contains(haystack string, needle string) bool {
return strings.Index(haystack, needle) == -1
}

func ContainsFromSlice(haystack string, needle []string) bool {
// TODO
return false
}

func ContainsAllFromSlice(haystack string, needle []string) bool {
Copy link
Contributor

@reindert-vetter reindert-vetter Mar 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of the following?
ContainsBySlice()
ContainsAllBySlice()
But it doesn't really matter to me 🤷‍♂️

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course. I will change this. I had just worked for some minutes on it and simply pushed the changes. More to come when I have the time to do so.

// TODO
return false
}

func EndsWith(haystack string, needle string) bool {
// TODO
return false
}

func Finish(value string, cap string) string {
// TODO
return ""
}

func Kebab(vale string) string {
// TODO
return ""
}

func Length(value string) int {
// TODO
return 0
}

func LimitCharacters(value string, limit int, end string) string{
// TODO
return ""
}

func LimitWords(value string, limit int, end string) string{
// TODO
return ""
}

func Lower(value string) string {
// TODO
return ""
}

func PadBoth(value string, length int, pad string) string {
// TODO
return ""
}

func PadLeft(value string, length int, pad string) string {
// TODO
return ""
}

func PadRight(value string, length int, pad string) string {
// TODO
return ""
}

func ReplaceArray(search string, replace []string, subject string) string {
// TODO
return ""
}

func ReplaceFirst(search string, replace string, subject string) string {
// TODO
return ""
}

func ReplaceLast(search string, replace string, subject string) string {
// TODO
return ""
}

func Start(value string, prefix string) string {
// TODO
return ""
}

func Slug(value string) string {
// TODO
return ""
}
func SlugWithDelimiter(value string, delimiter string) string {
// TODO
return ""
}

func Snake(value string) string {
// TODO
return ""
}

func SnakeWithDelimiter(value string, delimiter string) string {
// TODO
return ""
}

func StartsWith(haystack string, needle string) string {
// TODO
return ""
}

func Studly(value string) string {
// TODO
return ""
}

func UcFirst(value string) string {
// TODO
return ""
}

func Upper(value string) string {
// TODO
return ""
}

func Title(value string) string {
// TODO
return ""
}





















74 changes: 74 additions & 0 deletions str/str_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package str

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestAfter(t *testing.T) {
// TODO: What if nothing is found?
assert.Equal(t, "", After("", ""))
assert.Equal(t, "", After("hannah", ""))
assert.Equal(t, "", After("", "han"))
assert.Equal(t, "nah", After("hannah", "han"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I start each test with empty values as parameters. As an example:
assert.Equal(t, "", After("", ""))
assert.Equal(t, "", After("hannah", ""))
assert.Equal(t, "", After("", "hannah"))
(I'm not sure if the result is what it should be.)

Would you like to add that to this test and check it in the other tests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea.

assert.Equal(t, "nah", After("hannah", "n"))
assert.Equal(t, "nah", After("eee hannah", "han"))
assert.Equal(t, "nah", After("ééé hannah", "han"))
assert.Equal(t, "hannah", After("hannah", "xxxx"))
assert.Equal(t, "nah", After("han0nah", "0"))
assert.Equal(t, "nah", After("han2nah", "2"))
}

func TestAfterLast(t *testing.T) {
// TODO: What if nothing is found?
assert.Equal(t, "", After("", ""))
assert.Equal(t, "", After("hannah", ""))
assert.Equal(t, "", After("", "han"))
assert.Equal(t,"tte", AfterLast("yvette", "yve"))
assert.Equal(t,"e", AfterLast("yvette", "t"))
assert.Equal(t,"e", AfterLast("ééé yvette", "t"))
assert.Equal(t,"", AfterLast("yvette", "tte"))
assert.Equal(t,"yvette", AfterLast("yvette", "xxxx"))
assert.Equal(t,"te", AfterLast("yv0et0te", "0"))
assert.Equal(t,"te", AfterLast("yv0et0te", "0"))
assert.Equal(t,"te", AfterLast("yv2et2te", "2"))
assert.Equal(t,"foo", AfterLast("----foo", "---"))
}

func TestBefore(t *testing.T) {
assert.Equal(t, "han", Before("hannah", "nah"))
assert.Equal(t, "ha", Before("hannah", "n"))
assert.Equal(t, "ééé ", Before("ééé hannah", "han"))
assert.Equal(t, "hannah", Before("hannah", "xxxx"))
assert.Equal(t, "han", Before("han0nah", "0"))
assert.Equal(t, "han", Before("han0nah", "0"))
assert.Equal(t, "han", Before("han2nah", "2"))
}

func TestBeforeLast(t *testing.T) {
assert.Equal(t,"yve", BeforeLast("yvette", "tte"))
assert.Equal(t,"yvet", BeforeLast("yvette", "t"))
assert.Equal(t,"ééé ", BeforeLast("ééé yvette", "yve"))
assert.Equal(t,"", BeforeLast("yvette", "yve"))
assert.Equal(t,"yvette", BeforeLast("yvette", "xxxx"))
assert.Equal(t,"yvette", BeforeLast("yvette", ""))
assert.Equal(t,"yv0et", BeforeLast("yv0et0te", "0"))
assert.Equal(t,"yv0et", BeforeLast("yv0et0te", "0"))
assert.Equal(t,"yv2et", BeforeLast("yv2et2te", "2"))
}

func TestBetween(t *testing.T) {
assert.Equal(t,"abc", Between("abc", "", "c"))
assert.Equal(t,"abc", Between("abc", "a", ""))
assert.Equal(t,"abc", Between("abc", "", ""))
assert.Equal(t,"b", Between("abc", "a", "c"))
assert.Equal(t,"b", Between("dddabc", "a", "c"))
assert.Equal(t,"b", Between("abcddd", "a", "c"))
assert.Equal(t,"b", Between("dddabcddd", "a", "c"))
assert.Equal(t,"nn", Between("hannah", "ha", "ah"))
assert.Equal(t,"a]ab[b", Between("[a]ab[b]", "[", "]"))
assert.Equal(t,"foo", Between("foofoobar", "foo", "bar"))
assert.Equal(t,"bar", Between("foobarbar", "foo", "bar"))
}