Skip to content

Commit

Permalink
Split at every character if using empty string as delimiter
Browse files Browse the repository at this point in the history
  • Loading branch information
malthe committed Oct 20, 2016
1 parent 2a52a0d commit 0512954
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ All notable changes to the Pony compiler and standard library will be documented
(which may result in a copy) while `cpointer()` (also available on
`Array` objects) returns a pointer to the underlying array as-is
(issue #1309).
- `String.split("")` now splits the string at every character instead
of returning an array with a copy of the entire string as the only
element.

## [0.5.1] - 2016-10-15

Expand Down
47 changes: 32 additions & 15 deletions packages/builtin/string.pony
Original file line number Diff line number Diff line change
Expand Up @@ -993,15 +993,19 @@ actor Main
Adjacent delimiters result in a zero length entry in the array. For
example, `"1,,2".split(",") => ["1", "", "2"]`.
An empty string as delimiter will split at every character.
"""
let result = recover Array[String] end

if _size > 0 then
let chars = Array[U32](delim.size())

for rune in delim.runes() do
chars.push(rune)
end
let ds = delim.size()
let chars: (Array[U32] | None) =
if ds > 0 then
Array[U32](ds).concat(delim.runes())
else
None
end

var cur = recover String end
var i = USize(0)
Expand All @@ -1011,16 +1015,13 @@ actor Main
while i < _size do
(let c, let len) = utf32(i.isize())

if chars.contains(c) then
// If we find a delimeter, add the current string to the array.
occur = occur + 1

if (n > 0) and (occur >= n) then
break
end

result.push(cur = recover String end)
let found = match chars
| let chars': Array[U32] => chars'.contains(c)
else
true
end

if (ds == 0) or (found is false) then
// Add bytes to the current string.
var j = U8(0)

Expand All @@ -1030,7 +1031,23 @@ actor Main
end
end

i = i + len.usize()
let k = len.usize()

if found then
// If we find a delimeter, add the current string to the array.
occur = occur + 1

if (n > 0) and (occur >= n) then
if ds == 0 then
i = i + k
end
break
end

result.push(cur = recover String end)
end

i = i + k
end
end

Expand Down
6 changes: 6 additions & 0 deletions packages/builtin_test/_test.pony
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,12 @@ class iso _TestStringSplit is UnitTest
h.assert_eq[String](r(1), "2")
h.assert_eq[String](r(2), "3 4")

r = "1 2 3 4".split("" where n = 3)
h.assert_eq[USize](r.size(), 3)
h.assert_eq[String](r(0), "1")
h.assert_eq[String](r(1), " ")
h.assert_eq[String](r(2), "2 3 4")


class iso _TestStringJoin is UnitTest
"""
Expand Down

0 comments on commit 0512954

Please sign in to comment.