Commit 819e0b29 authored by Martin Möhrmann's avatar Martin Möhrmann Committed by Ian Lance Taylor

strings: improve explode and correct comment

Merges explodetests into splittests which already contain
some of the tests that cover explode.

Adds a test to cover the utf8.RuneError branch in explode.

name      old time/op  new time/op  delta
Split1-2  14.9ms ± 0%  14.2ms ± 0%  -4.06%  (p=0.000 n=47+49)

Change-Id: I00f796bd2edab70e926ea9e65439d820c6a28254
Reviewed-on: https://go-review.googlesource.com/21609
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 3f66d8c8
...@@ -12,32 +12,25 @@ import ( ...@@ -12,32 +12,25 @@ import (
"unicode/utf8" "unicode/utf8"
) )
// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n < 0 means no limit). // explode splits s into a slice of UTF-8 strings,
// Invalid UTF-8 sequences become correct encodings of U+FFF8. // one string per Unicode character up to a maximum of n (n < 0 means no limit).
// Invalid UTF-8 sequences become correct encodings of U+FFFD.
func explode(s string, n int) []string { func explode(s string, n int) []string {
if n == 0 {
return nil
}
l := utf8.RuneCountInString(s) l := utf8.RuneCountInString(s)
if n <= 0 || n > l { if n < 0 || n > l {
n = l n = l
} }
a := make([]string, n) a := make([]string, n)
var size int for i := 0; i < n-1; i++ {
var ch rune ch, size := utf8.DecodeRuneInString(s)
i, cur := 0, 0 a[i] = s[:size]
for ; i+1 < n; i++ { s = s[size:]
ch, size = utf8.DecodeRuneInString(s[cur:])
if ch == utf8.RuneError { if ch == utf8.RuneError {
a[i] = string(utf8.RuneError) a[i] = string(utf8.RuneError)
} else {
a[i] = s[cur : cur+size]
} }
cur += size
} }
// add the rest, if there is any if n > 0 {
if cur < len(s) { a[n-1] = s
a[i] = s[cur:]
} }
return a return a
} }
......
...@@ -256,31 +256,6 @@ func BenchmarkIndexByte(b *testing.B) { ...@@ -256,31 +256,6 @@ func BenchmarkIndexByte(b *testing.B) {
} }
} }
var explodetests = []struct {
s string
n int
a []string
}{
{"", -1, []string{}},
{abcd, 4, []string{"a", "b", "c", "d"}},
{faces, 3, []string{"☺", "☻", "☹"}},
{abcd, 2, []string{"a", "bcd"}},
}
func TestExplode(t *testing.T) {
for _, tt := range explodetests {
a := SplitN(tt.s, "", tt.n)
if !eq(a, tt.a) {
t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a)
continue
}
s := Join(a, "")
if s != tt.s {
t.Errorf(`Join(explode(%q, %d), "") = %q`, tt.s, tt.n, s)
}
}
}
type SplitTest struct { type SplitTest struct {
s string s string
sep string sep string
...@@ -289,19 +264,23 @@ type SplitTest struct { ...@@ -289,19 +264,23 @@ type SplitTest struct {
} }
var splittests = []SplitTest{ var splittests = []SplitTest{
{"", "", -1, []string{}},
{abcd, "", 2, []string{"a", "bcd"}},
{abcd, "", 4, []string{"a", "b", "c", "d"}},
{abcd, "", -1, []string{"a", "b", "c", "d"}},
{faces, "", -1, []string{"☺", "☻", "☹"}},
{faces, "", 3, []string{"☺", "☻", "☹"}},
{faces, "", 17, []string{"☺", "☻", "☹"}},
{"☺�☹", "", -1, []string{"☺", "�", "☹"}},
{abcd, "a", 0, nil}, {abcd, "a", 0, nil},
{abcd, "a", -1, []string{"", "bcd"}}, {abcd, "a", -1, []string{"", "bcd"}},
{abcd, "z", -1, []string{"abcd"}}, {abcd, "z", -1, []string{"abcd"}},
{abcd, "", -1, []string{"a", "b", "c", "d"}},
{commas, ",", -1, []string{"1", "2", "3", "4"}}, {commas, ",", -1, []string{"1", "2", "3", "4"}},
{dots, "...", -1, []string{"1", ".2", ".3", ".4"}}, {dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
{faces, "☹", -1, []string{"☺☻", ""}}, {faces, "☹", -1, []string{"☺☻", ""}},
{faces, "~", -1, []string{faces}}, {faces, "~", -1, []string{faces}},
{faces, "", -1, []string{"☺", "☻", "☹"}},
{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}}, {"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
{"1 2", " ", 3, []string{"1", "2"}}, {"1 2", " ", 3, []string{"1", "2"}},
{"123", "", 2, []string{"1", "23"}},
{"123", "", 17, []string{"1", "2", "3"}},
} }
func TestSplit(t *testing.T) { func TestSplit(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment