Skip to content
This repository has been archived by the owner on Apr 1, 2023. It is now read-only.

Commit

Permalink
Add the functions of SplitN
Browse files Browse the repository at this point in the history
  • Loading branch information
xgfone committed Dec 16, 2016
1 parent 79432e3 commit fb98619
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 11 deletions.
18 changes: 18 additions & 0 deletions str/string_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,21 @@ func ExampleSplitString() {
// Output:
// [len=4: ab-fg-12-45]
}

func ExampleSplitN() {
s := " 1 2 3 "

s1 := str.SplitN(s, unicode.IsSpace, -1)
fmt.Printf("[len=%v: -%v-%v-%v-]\n", len(s1), s1[0], s1[1], s1[2])

s2 := str.SplitN(s, unicode.IsSpace, 0)
fmt.Printf("[len=%v: -%v-]\n", len(s2), s2[0])

s3 := str.SplitN(s, unicode.IsSpace, 1)
fmt.Printf("[len=%v: -%v-%v-]\n", len(s3), s3[0], s3[1])

// Output:
// [len=3: -1-2-3-]
// [len=1: - 1 2 3 -]
// [len=2: -1-2 3 -]
}
53 changes: 42 additions & 11 deletions str/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,52 @@ import (
//
// Notice: SplitSpace(s) == Split(s, unicode.IsSpace).
func SplitSpace(s string) []string {
return Split(s, unicode.IsSpace)
return SplitSpaceN(s, -1)
}

// SplitString splits the string of s by sep, but is not the same as
// strings.Split(), which the rune in sep arbitrary combination. For example,
// SplitString("abcdefg-12345", "3-edc") == []string{"ab", "fg", "12", "45"}.
func SplitString(s string, sep string) []string {
return Split(s, func(c rune) bool {
return SplitStringN(s, sep, -1)
}

// Split splits the string of s by the filter. Split will pass each rune to the
// filter to determine whether it is the separator.
func Split(s string, filter func(c rune) bool) []string {
return SplitN(s, filter, -1)
}

// SplitSpaceN is the same as SplitStringN, but the whitespace.
func SplitSpaceN(s string, number int) []string {
return SplitN(s, unicode.IsSpace, number)
}

// SplitStringN is the same as SplitN, but the separator is the string of sep.
func SplitStringN(s string, sep string, number int) []string {
return SplitN(s, func(c rune) bool {
for _, r := range sep {
if r == c {
return true
}
}
return false
})
}, number)
}

// Split splits the string of s by the filter. Split will pass each rune to the
// filter to determine whether it is the separator.
func Split(s string, filter func(c rune) bool) []string {
// SplitN splits the string of s by the filter. Split will pass each rune to the
// filter to determine whether it is the separator, but only number times.
//
// If number is equal to 0, don't split; greater than 0, only split number times;
// less than 0, don't limit. If the leading rune is the separator, it doesn't
// consume the split number.
//
// Notice: The result does not have the element of nil.
func SplitN(s string, filter func(c rune) bool, number int) []string {
if number == 0 {
return []string{s}
}

for i, c := range s {
if !filter(c) {
s = s[i:]
Expand All @@ -44,17 +70,22 @@ func Split(s string, filter func(c rune) bool) []string {

results := make([]string, 0)
buf := bytes.NewBuffer(nil)
is_new := false
for _, c := range s {
isNew := false
for i, c := range s {
if filter(c) {
is_new = true
isNew = true
continue
}

if is_new {
if isNew {
results = append(results, buf.String())
buf = bytes.NewBuffer(nil)
is_new = false
isNew = false
number--
if number == 0 {
buf.WriteString(s[i:])
break
}
}

buf.WriteRune(c)
Expand Down

0 comments on commit fb98619

Please sign in to comment.