From 05d3939b11fa24d1a3aeb0a7be327b84b2ec3473 Mon Sep 17 00:00:00 2001 From: Frotty Date: Sun, 4 Oct 2026 16:05:29 +0200 Subject: [PATCH 1/2] Add specialized array string splitting API --- wurst/util/StringUtils.wurst | 18 ++++++++++++++++++ wurst/util/StringUtilsTests.wurst | 20 +++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/wurst/util/StringUtils.wurst b/wurst/util/StringUtils.wurst index f2411f59..cf353fc1 100644 --- a/wurst/util/StringUtils.wurst +++ b/wurst/util/StringUtils.wurst @@ -1,6 +1,7 @@ package StringUtils import NoWurst import LinkedList +import ArrayList import Texttag import Interpolation import TypeCasting @@ -108,6 +109,23 @@ public function string.split(string splitBy) returns LinkedList str = second return list +/** Splits into specialized contiguous storage, preserving empty and trailing fields. + An empty delimiter returns the original string as one field. The caller owns the list. */ +public function string.splitToArray(string delimiter) returns ArrayList + let result = new ArrayList() + let offset = delimiter.length() + if offset == 0 + result.add(this) + return result + var start = 0 + var position = this.indexOf(delimiter, start) + while position >= 0 + result.add(start == position ? "" : this.substring(start, position)) + start = position + offset + position = this.indexOf(delimiter, start) + result.add(start == this.length() ? "" : this.substring(start, this.length())) + return result + /** Replaces consecutive repeats of the same string with a single instance Turns "strstr" into "str" */ public function string.reduce(string reduced) returns string diff --git a/wurst/util/StringUtilsTests.wurst b/wurst/util/StringUtilsTests.wurst index 1cf2bc8e..fd8cfa00 100644 --- a/wurst/util/StringUtilsTests.wurst +++ b/wurst/util/StringUtilsTests.wurst @@ -23,6 +23,24 @@ import ObjectIds (list.size() == 1).assertTrue() destroy list +@Test function splitToArrayPreservesEmptyFieldsAndMultiCharacterDelimiters() + let fields = "::alpha::::beta::".splitToArray("::") + fields.size().assertEquals(5) + fields.get(0).assertEquals("") + fields.get(1).assertEquals("alpha") + fields.get(2).assertEquals("") + fields.get(3).assertEquals("beta") + fields.get(4).assertEquals("") + destroy fields + let empty = "".splitToArray(",") + empty.size().assertEquals(1) + empty.get(0).assertEquals("") + destroy empty + let unchanged = "alpha".splitToArray("") + unchanged.size().assertEquals(1) + unchanged.get(0).assertEquals("alpha") + destroy unchanged + @Test function testJoin() let list = new LinkedList() ..add("this", "is", "a", "string") @@ -74,4 +92,4 @@ import ObjectIds "1-2".isNumber().assertFalse() @Test function testReplaceChars() - "abca".replaceChars("ca", "d").assertEquals("dbdd") \ No newline at end of file + "abca".replaceChars("ca", "d").assertEquals("dbdd") From 3d0b5437c50295515d54a1b06d96fc99969702f8 Mon Sep 17 00:00:00 2001 From: Frotty Date: Sun, 4 Oct 2026 16:17:59 +0200 Subject: [PATCH 2/2] Preserve null strings in array splitting --- wurst/util/StringUtils.wurst | 2 +- wurst/util/StringUtilsTests.wurst | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/wurst/util/StringUtils.wurst b/wurst/util/StringUtils.wurst index cf353fc1..37701db8 100644 --- a/wurst/util/StringUtils.wurst +++ b/wurst/util/StringUtils.wurst @@ -114,7 +114,7 @@ public function string.split(string splitBy) returns LinkedList public function string.splitToArray(string delimiter) returns ArrayList let result = new ArrayList() let offset = delimiter.length() - if offset == 0 + if this == null or offset == 0 result.add(this) return result var start = 0 diff --git a/wurst/util/StringUtilsTests.wurst b/wurst/util/StringUtilsTests.wurst index fd8cfa00..bf1fa702 100644 --- a/wurst/util/StringUtilsTests.wurst +++ b/wurst/util/StringUtilsTests.wurst @@ -41,6 +41,13 @@ import ObjectIds unchanged.get(0).assertEquals("alpha") destroy unchanged +@Test function splitToArrayPreservesNullInput() + string input = null + let fields = input.splitToArray(",") + fields.size().assertEquals(1) + (fields.get(0) == null).assertTrue() + destroy fields + @Test function testJoin() let list = new LinkedList() ..add("this", "is", "a", "string")