Skip to content

Commit 02d84d8

Browse files
committed
libcore: add splitn to split a string N times.
1 parent 8e54e74 commit 02d84d8

File tree

2 files changed

+59
-18
lines changed

2 files changed

+59
-18
lines changed

src/libcore/str.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ String manipulation.
66

77
export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len,
88
byte_len_range, index,
9-
rindex, find, starts_with, ends_with, substr, slice, split, split_str,
10-
concat, connect, to_upper, replace, char_slice, trim_left, trim_right,
11-
trim, unshift_char, shift_char, pop_char, push_char, is_utf8,
12-
from_chars, to_chars, char_len, char_len_range, char_at, bytes,
13-
is_ascii, shift_byte, pop_byte,
9+
rindex, find, starts_with, ends_with, substr, slice, split, splitn,
10+
split_str, concat, connect, to_upper, replace, char_slice, trim_left,
11+
trim_right, trim, unshift_char, shift_char, pop_char, push_char,
12+
is_utf8, from_chars, to_chars, char_len, char_len_range, char_at,
13+
bytes, is_ascii, shift_byte, pop_byte,
1414
unsafe_from_byte, unsafe_from_bytes, from_char, char_range_at,
1515
str_from_cstr, sbuf, as_buf, push_byte, utf8_char_width, safe_slice,
1616
contains, iter_chars, loop_chars, loop_chars_sub,
@@ -744,6 +744,32 @@ fn split(s: str, sep: u8) -> [str] {
744744
ret v;
745745
}
746746

747+
/*
748+
Function: splitn
749+
750+
Split a string at each occurance of a given separator up to count times.
751+
752+
Returns:
753+
754+
A vector containing all the strings between each occurance of the separator
755+
*/
756+
fn splitn(s: str, sep: u8, count: uint) -> [str] {
757+
let v = [];
758+
let accum = "";
759+
let n = count;
760+
let ends_with_sep: bool = false;
761+
for c in s {
762+
if n > 0u && c == sep {
763+
n -= 1u;
764+
v += [accum];
765+
accum = "";
766+
ends_with_sep = true;
767+
} else { accum += unsafe_from_byte(c); ends_with_sep = false; }
768+
}
769+
if byte_len(accum) != 0u || ends_with_sep { v += [accum]; }
770+
ret v;
771+
}
772+
747773
/*
748774
Function: split_str
749775

src/test/stdtest/str.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,37 @@ fn test_index_and_rindex() {
4141

4242
#[test]
4343
fn test_split() {
44-
fn t(s: str, c: char, i: int, k: str) {
45-
log "splitting: " + s;
46-
log i;
44+
fn t(s: str, c: char, u: [str]) {
45+
log "split: " + s;
4746
let v = str::split(s, c as u8);
4847
log "split to: ";
49-
for z: str in v { log z; }
50-
log "comparing: " + v[i] + " vs. " + k;
51-
assert (str::eq(v[i], k));
48+
log v;
49+
assert (vec::all2(v, u, { |a,b| a == b }));
5250
}
53-
t("abc.hello.there", '.', 0, "abc");
54-
t("abc.hello.there", '.', 1, "hello");
55-
t("abc.hello.there", '.', 2, "there");
56-
t(".hello.there", '.', 0, "");
57-
t(".hello.there", '.', 1, "hello");
58-
t("...hello.there.", '.', 3, "hello");
59-
t("...hello.there.", '.', 5, "");
51+
t("abc.hello.there", '.', ["abc", "hello", "there"]);
52+
t(".hello.there", '.', ["", "hello", "there"]);
53+
t("...hello.there.", '.', ["", "", "", "hello", "there", ""]);
54+
}
55+
56+
#[test]
57+
fn test_splitn() {
58+
fn t(s: str, c: char, n: uint, u: [str]) {
59+
log "splitn: " + s;
60+
let v = str::splitn(s, c as u8, n);
61+
log "split to: ";
62+
log v;
63+
log "comparing vs. ";
64+
log u;
65+
assert (vec::all2(v, u, { |a,b| a == b }));
66+
}
67+
t("abc.hello.there", '.', 0u, ["abc.hello.there"]);
68+
t("abc.hello.there", '.', 1u, ["abc", "hello.there"]);
69+
t("abc.hello.there", '.', 2u, ["abc", "hello", "there"]);
70+
t("abc.hello.there", '.', 3u, ["abc", "hello", "there"]);
71+
t(".hello.there", '.', 0u, [".hello.there"]);
72+
t(".hello.there", '.', 1u, ["", "hello.there"]);
73+
t("...hello.there.", '.', 3u, ["", "", "", "hello.there."]);
74+
t("...hello.there.", '.', 5u, ["", "", "", "hello", "there", ""]);
6075
}
6176

6277
#[test]

0 commit comments

Comments
 (0)