This repository has been archived by the owner on Aug 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
string.go
102 lines (84 loc) · 2.05 KB
/
string.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package iter
import (
"strings"
"unicode/utf8"
)
// Runes returns an iterator over the runes of the input string.
// Runes(s).Collect() should be equivalent to []rune(s).
func Runes(s string) Iter[rune] {
b := []byte(s)
i := 0
return func() (rune, bool) {
if len(b) <= i {
var r rune
return r, false
}
r, size := utf8.DecodeRune(b[i:])
i += size
return r, true
}
}
// SplitByRune returns an iterator over the substrings of the input string
// between occurrences of the provided rune. SplitByRune(s, r).Collect() should
// be equivalent to strings.Split(s, string(r)) for valid runes.
func SplitByRune(s string, r rune) Iter[string] {
index := 0
return func() (string, bool) {
if index < len(s) {
sepIndex := strings.IndexRune(s[index:], r)
if sepIndex == -1 {
res := s[index:]
index = len(s) + 1
return res, true
}
res := s[index : index+sepIndex]
index += sepIndex + utf8.RuneLen(r)
return res, true
} else if index == len(s) {
index++
return "", true
}
return "", false
}
}
// SplitByString returns an iterator over the substrings of the input string
// between occurrences of the provided separator string.
// SplitByString(s, sep).Collect() should be equivalent to
// strings.Split(s, sep).
func SplitByString(s string, sep string) Iter[string] {
index := 0
if sep == "" {
return func() (string, bool) {
if index < len(s)-1 {
r, size := utf8.DecodeRuneInString(s[index:])
prevIndex := index
index += size
if r == utf8.RuneError {
return string(utf8.RuneError), true
}
return s[prevIndex:index], true
} else if index == len(s)-1 {
index++
return s[len(s)-1:], true
}
return "", false
}
}
return func() (string, bool) {
if index < len(s) {
sepIndex := strings.Index(s[index:], sep)
if sepIndex == -1 {
res := s[index:]
index = len(s) + 1
return res, true
}
res := s[index : index+sepIndex]
index += sepIndex + len(sep)
return res, true
} else if index == len(s) {
index++
return "", true
}
return "", false
}
}