How String.Split() works in C#
Check the Microsoft documentation on String.Split() >>
The optional parameter of type StringSplitOptions allows you to specify options such as whether to omit empty substrings from the returned array or trim whitespace from substrings. This enumeration supports a bitwise combination of its member values.
How strSplit() works in X++
It works in the same way as String.Split() with the StringSplitOptions.None parameter - it splits the input string into a list of substrings delimited by elements in the specified delimiter string. This means that it doesn't trim the substrings nor omit empty substrings from the resulting list, so you can get:
strSplit("a ; b ;; ", ";") -> List {"a ", " b ", "", " "}
The question is, what to do if we want to get the following result instead:
List {"a", "b"}
Of course, we can always use String.Split() in X++ as well, but for the sake of simplicity of the use of the method and to avoid dealing with .NET Arrays for input delimiters and the returning array of substrings, we have created our "improved" version of strSplit() in x++. Let's take a look!
We made strSplit() working as in C#
Implementation
We introduce a similar enum to StringSplitOptions in .NET - enum DocStringSplitOptions:
- None (0) - the default mode, which doesn't trim the substrings nor omit empty substrings from the resulting list
- RemoveEmptyEntries (1) - omit all substrings that contain an empty string from the resulting list
- TrimEntries (2) - trim white-space characters from each substrings in the resulting list
If RemoveEmptyEntries and TrimEntries are specified together, then the substrings that consist only of white-space characters are also removed from the resulting list.
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 |
/// <summary> /// Splits a string into a list of substrings delimited by elements in the specified delimiter string. /// This is done using the specified string splitting options, which can be: /// - None - the default mode, which doesn't trim the substrings nor omit empty substrings from the resulting list /// - RemoveEmptyEntries - omit all substrings that contain an empty string from the resulting list /// - TrimEntries - trim white-space characters from each substring in the result /// If RemoveEmptyEntries and TrimEntries are specified together, then substrings that consist only of /// white-space characters are also removed from the result. /// </summary> /// <param name = "_stringToSplit">The string to split into a list.</param> /// <param name = "_delimiters">A string of delimiter characters.</param> /// <param name = "_stringSplitOptions"> /// A bitwise combination of the DocStringSplitOptions enum values that specifies whether to trim /// substrings and include empty substrings. /// </param> /// <returns>A list of substrings from the _stringToSplit parameter.</returns> /// <remarks> /// Each character in the _delimiter string is used to split the _stringToSplit parameter. /// The code is modified version of Global::strSplit() method. /// </remarks> public static List strSplit(str _stringToSplit, str _delimiters, int _stringSplitOptions = DocStringSplitOptions::None) { List list = new List(Types::String); int oldPos = 1; int pos; int strLength = strLen(_stringToSplit); do { // Find next position of the delimiter in the string pos = strFind(_stringToSplit, _delimiters, oldPos, strLength); if (!pos) { pos = strLength + 1; } // Get a substring from the string str s = subStr(_stringToSplit, oldPos, pos-oldPos); // Trim a substring depending on the string splitting options if (_stringSplitOptions == DocStringSplitOptions::TrimEntries || _stringSplitOptions == (DocStringSplitOptions::RemoveEmptyEntries | DocStringSplitOptions::TrimEntries)) { s = strLRTrim(s); } // Add a substring to the list depending on the string splitting options if (!(s == '' && (_stringSplitOptions == DocStringSplitOptions::RemoveEmptyEntries || _stringSplitOptions == (DocStringSplitOptions::RemoveEmptyEntries | DocStringSplitOptions::TrimEntries)))) { // Add a substring to the list list.addEnd(s); } oldPos = pos+1; } while (pos <= strLength); return list; } |
Unit tests
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
/// <summary> /// The class DocGlobalHelperStrSplitTest is used as a test unit for the method strSplit() in the class DocGlobalHelper. /// </summary> public class DocGlobalHelperStrSplitTest extends SysTestCase { [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit01() { // Arrange str stringToSplit = ""; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::None; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 1); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit02() { // Arrange str stringToSplit = ""; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 0); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit03() { // Arrange str stringToSplit = ""; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 1); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit04() { // Arrange str stringToSplit = ""; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries | DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 0); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit05() { // Arrange str stringToSplit = " "; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::None; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 1); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit06() { // Arrange str stringToSplit = " "; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 1); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit07() { // Arrange str stringToSplit = " "; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 1); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit08() { // Arrange str stringToSplit = " "; str delimiters = ";"; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries | DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 0); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit09() { // Arrange str stringToSplit = "a;b, "; str delimiters = ",;"; int stringSplitOptions = DocStringSplitOptions::None; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 3); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit10() { // Arrange str stringToSplit = "a;b, "; str delimiters = ",;"; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 3); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit11() { // Arrange str stringToSplit = "a;b, "; str delimiters = ",;"; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries | DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 2); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit12() { // Arrange str stringToSplit = "a;b, "; str delimiters = ",;"; int stringSplitOptions = DocStringSplitOptions::None | DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 3); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit13() { // Arrange str stringToSplit = "a b "; str delimiters = " "; int stringSplitOptions = DocStringSplitOptions::None; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 4); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit14() { // Arrange str stringToSplit = "a b "; str delimiters = " "; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 2); } [SysTestMethodAttribute, SysTestGranularityAttribute(SysTestGranularity::Unit)] public void testStrSplit15() { // Arrange str stringToSplit = "a b "; str delimiters = " "; int stringSplitOptions = DocStringSplitOptions::RemoveEmptyEntries | DocStringSplitOptions::TrimEntries; // Act List result = DocGlobalHelper::strSplit(stringToSplit, delimiters, stringSplitOptions); // Assert this.assertTrue(result.elements() == 2); } } |