Skip to content

Commit 15c7ce2

Browse files
committed
Merge branch 'feature/28-add-RandomString-function' into develop
Fixes #28
2 parents 3a69083 + 5e0cf73 commit 15c7ce2

File tree

4 files changed

+196
-47
lines changed

4 files changed

+196
-47
lines changed

collection/707.dat

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function RandomString(const SL: Classes.TStrings): string; overload;
2+
begin
3+
if SL.Count = 0 then
4+
raise SysUtils.EArgumentException.Create(
5+
'RandomString called with empty string list'
6+
);
7+
Result := SL[Random(SL.Count)];
8+
end;

collection/string.ini

+11
Original file line numberDiff line numberDiff line change
@@ -1807,3 +1807,14 @@ DelphiXE4=Y
18071807
Delphi10S=Y
18081808
Delphi12A=Y
18091809
FPC=Y
1810+
1811+
[RandomString]
1812+
DescEx="<p>Returns a random string from the given non-empty string list.</p><p>An <var>EArgumentException</var> exception is raised if the string list is empty.</p>"
1813+
Extra="<p>The Delphi RTL has a similar <var>RandomFrom</var> function in <var>StrUtils</var> that returns a random string from a string array.</p>"
1814+
Units=SysUtils,Classes
1815+
TestInfo=advanced
1816+
AdvancedTest.Level=unit-tests
1817+
AdvancedTest.URL="https://github.com/delphidabbler/code-snippets/tree/master/tests/Cat-String"
1818+
Snip=707.dat
1819+
DelphiXE=Y
1820+
Delphi12A=Y

tests/Cat-String/TestUStringCatSnippets.pas

+50-1
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@ interface
88
type
99
TestStringCatSnippets = class(TTestCase)
1010
private
11+
procedure RandomString_Exception;
1112
published
1213
procedure TestStripAccelChars;
1314
procedure TestReverseStr;
1415
procedure TestReverseStrR;
1516
procedure TestIsNumeric;
1617
procedure TestSplitString;
1718
procedure TestParseStr;
19+
procedure TestRandomString;
1820
end;
1921

2022
implementation
2123

2224
uses
23-
Classes;
25+
SysUtils, Classes;
2426

2527
function IsEqualStringList(const Expected, Actual: TStrings): Boolean;
2628
var
@@ -37,6 +39,18 @@ function IsEqualStringList(const Expected, Actual: TStrings): Boolean;
3739

3840
{ TestStringCatSnippets }
3941

42+
procedure TestStringCatSnippets.RandomString_Exception;
43+
var
44+
SL: TStrings;
45+
begin
46+
SL := TStringList.Create;
47+
try
48+
RandomString(SL);
49+
finally
50+
SL.Free;
51+
end;
52+
end;
53+
4054
procedure TestStringCatSnippets.TestIsNumeric;
4155
begin
4256
CheckTrue(IsNumeric('123', False, False), 'Test 1');
@@ -133,6 +147,41 @@ procedure TestStringCatSnippets.TestParseStr;
133147
end;
134148
end;
135149

150+
procedure TestStringCatSnippets.TestRandomString;
151+
var
152+
SL5, SL1: TStrings;
153+
S: string;
154+
Idx, I: Integer;
155+
begin
156+
SL1 := nil;
157+
SL5 := nil;
158+
try
159+
SL5 := TStringList.Create;
160+
SL5.Add('one');
161+
SL5.Add('two');
162+
SL5.Add('three');
163+
SL5.Add('four');
164+
SL5.Add('five');
165+
for I := 1 to 5 do
166+
begin
167+
S := RandomString(SL5);
168+
Idx := SL5.IndexOf(S);
169+
CheckTrue(Idx >= 0, Format('SL5.%d', [I]));
170+
SL5.Delete(Idx);
171+
end;
172+
173+
SL1 := TStringList.Create;
174+
SL1.Add('only');
175+
S := RandomString(SL1);
176+
CheckEquals('only', S, '#2');
177+
finally
178+
SL5.Free;
179+
SL1.Free;
180+
end;
181+
182+
CheckException(RandomString_Exception, EArgumentException, 'Exception');
183+
end;
184+
136185
procedure TestStringCatSnippets.TestReverseStr;
137186
begin
138187
CheckEquals('derf', ReverseStr('fred'), 'Test 1');

tests/Cat-String/UStringCatSnippets.pas

+127-46
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
{
2-
* This file was generated from the DelphiDabbler Code Snippets collection.
3-
*
4-
* See https://github.com/delphidabsbler/code-snippets/tree/master/LICENSE.md for
5-
* full license & copyright information.
2+
* This unit was generated automatically. It incorporates a selection of source
3+
* code taken from the Code Snippets Database at
4+
* https://github.com/delphidabbler/code-snippets.
5+
*
6+
* The unit is copyright © 2005-2025 by Peter Johnson & Contributors and is
7+
* licensed under the MIT License (https://opensource.org/licenses/MIT).
8+
*
9+
* Generated on : Sat, 05 Apr 2025 12:14:56 GMT.
10+
* Generated by : DelphiDabbler CodeSnip Release 4.24.0.
11+
*
12+
* The latest version of CodeSnip is available from the CodeSnip GitHub project
13+
* at https://github.com/delphidabbler/codesnip.
614
}
715

816
unit UStringCatSnippets;
917

1018
{$IFNDEF FPC}
1119
{$IFDEF CONDITIONALEXPRESSIONS}
20+
{$IF CompilerVersion >= 24.00}
21+
{$LEGACYIFEND ON}
22+
{$IFEND}
1223
{$IF CompilerVersion >= 14.00}
1324
{$WARN SYMBOL_PLATFORM OFF}
1425
{$WARN SYMBOL_DEPRECATED OFF}
@@ -29,31 +40,116 @@
2940
interface
3041

3142
uses
32-
SysUtils, StrUtils, Classes, Windows;
43+
SysUtils, Classes, StrUtils;
3344

34-
function StripAccelChars(const S: string): string;
45+
{
46+
Checks if the string Value contains a valid numeric value and returns True if
47+
so or False if not.
48+
If AllowFloat is true then Value may contain a floating point number,
49+
otherwise it must be an integer. If TrimWhiteSpace is True any white space
50+
surrounding Value is trimmed before testing.
51+
}
52+
function IsNumeric(Value: string; const AllowFloat: Boolean;
53+
const TrimWhiteSpace: Boolean = True): Boolean;
54+
55+
{
56+
Splits the string StrToParse into segments separated by Delimiter and stores
57+
each segment in turn in string list Words, replacing any existing content.
58+
}
59+
procedure ParseStr(const StrToParse: string; const Delimiter: Char;
60+
const Words: Classes.TStringList);
3561

62+
{
63+
Returns a random string from the given non-empty string list.
64+
An EArgumentException exception is raised if the string list is empty.
65+
}
66+
function RandomString(const SL: Classes.TStrings): string; overload;
67+
68+
{
69+
Returns the reverse of the given string.
70+
}
3671
function ReverseStr(S: string): string;
3772

73+
{
74+
Returns the reverse of the given string.
75+
}
3876
function ReverseStrR(const S: string): string;
3977

40-
function IsNumeric(Value: string; const AllowFloat: Boolean;
41-
const TrimWhiteSpace: Boolean = True): Boolean;
42-
78+
{
79+
Splits the string AText into segments separated by Delimiter and creates and
80+
returns a string list containing the segments.
81+
The caller is responsible for freeing the returnd string list object.
82+
}
4383
function SplitString(const AText, ADelimiter: string): Classes.TStringList;
4484

45-
procedure ParseStr(const StrToParse: string; const Delimiter: Char;
46-
const Words: Classes.TStringList);
85+
{
86+
Strips all accelerator ('&') characters from the given string and returns the
87+
resulting string.
88+
}
89+
function StripAccelChars(const S: string): string;
4790

4891
implementation
4992

50-
function StripAccelChars(const S: string): string;
93+
{
94+
Checks if the string Value contains a valid numeric value and returns True if
95+
so or False if not.
96+
If AllowFloat is true then Value may contain a floating point number,
97+
otherwise it must be an integer. If TrimWhiteSpace is True any white space
98+
surrounding Value is trimmed before testing.
99+
}
100+
function IsNumeric(Value: string; const AllowFloat: Boolean;
101+
const TrimWhiteSpace: Boolean = True): Boolean;
102+
var
103+
ValueInt: Int64; // dummy integer value
104+
ValueFloat: Extended; // dummy float value
51105
begin
52-
Result := SysUtils.StringReplace(
53-
S, '&', SysUtils.EmptyStr, [SysUtils.rfReplaceAll]
54-
);
106+
if TrimWhiteSpace then
107+
Value := SysUtils.Trim(Value);
108+
// Check for valid integer
109+
Result := SysUtils.TryStrToInt64(Value, ValueInt);
110+
if not Result and AllowFloat then
111+
// Wasn't valid as integer, try float
112+
Result := SysUtils.TryStrToFloat(Value, ValueFloat);
113+
end;
114+
115+
{
116+
Splits the string StrToParse into segments separated by Delimiter and stores
117+
each segment in turn in string list Words, replacing any existing content.
118+
}
119+
procedure ParseStr(const StrToParse: string; const Delimiter: Char;
120+
const Words: Classes.TStringList);
121+
var
122+
TmpInStr: string;
123+
begin
124+
TmpInStr := StrToParse;
125+
Words.Clear;
126+
if Length(TmpInStr) > 0 then
127+
begin
128+
while Pos(Delimiter, TmpInStr) > 0 do
129+
begin
130+
Words.Append(Copy(TmpInStr, 1, Pos(Delimiter, TmpInStr) - 1));
131+
Delete(TmpInStr, 1, Pos(Delimiter, TmpInStr));
132+
end;
133+
Words.Append(TmpInStr);
134+
end;
55135
end;
56136

137+
{
138+
Returns a random string from the given non-empty string list.
139+
An EArgumentException exception is raised if the string list is empty.
140+
}
141+
function RandomString(const SL: Classes.TStrings): string; overload;
142+
begin
143+
if SL.Count = 0 then
144+
raise SysUtils.EArgumentException.Create(
145+
'RandomString called with empty string list'
146+
);
147+
Result := SL[Random(SL.Count)];
148+
end;
149+
150+
{
151+
Returns the reverse of the given string.
152+
}
57153
function ReverseStr(S: string): string;
58154
begin
59155
Result := SysUtils.EmptyStr;
@@ -64,6 +160,9 @@ function ReverseStr(S: string): string;
64160
end;
65161
end;
66162

163+
{
164+
Returns the reverse of the given string.
165+
}
67166
function ReverseStrR(const S: string): string;
68167
begin
69168
if SysUtils.AnsiSameText(S, SysUtils.EmptyStr) or (System.Length(S) = 1) then
@@ -73,21 +172,11 @@ function ReverseStrR(const S: string): string;
73172
+ ReverseStrR(StrUtils.LeftStr(S, System.Length(S) - 1))
74173
end;
75174

76-
function IsNumeric(Value: string; const AllowFloat: Boolean;
77-
const TrimWhiteSpace: Boolean = True): Boolean;
78-
var
79-
ValueInt: Int64; // dummy integer value
80-
ValueFloat: Extended; // dummy float value
81-
begin
82-
if TrimWhiteSpace then
83-
Value := SysUtils.Trim(Value);
84-
// Check for valid integer
85-
Result := SysUtils.TryStrToInt64(Value, ValueInt);
86-
if not Result and AllowFloat then
87-
// Wasn't valid as integer, try float
88-
Result := SysUtils.TryStrToFloat(Value, ValueFloat);
89-
end;
90-
175+
{
176+
Splits the string AText into segments separated by Delimiter and creates and
177+
returns a string list containing the segments.
178+
The caller is responsible for freeing the returnd string list object.
179+
}
91180
function SplitString(const AText, ADelimiter: string): Classes.TStringList;
92181
var
93182
LTxt, LTmp: string;
@@ -104,23 +193,15 @@ function SplitString(const AText, ADelimiter: string): Classes.TStringList;
104193
Result.Add(LTxt);
105194
end;
106195

107-
procedure ParseStr(const StrToParse: string; const Delimiter: Char;
108-
const Words: Classes.TStringList);
109-
var
110-
TmpInStr: string;
196+
{
197+
Strips all accelerator ('&') characters from the given string and returns the
198+
resulting string.
199+
}
200+
function StripAccelChars(const S: string): string;
111201
begin
112-
TmpInStr := StrToParse;
113-
Words.Clear;
114-
if Length(TmpInStr) > 0 then
115-
begin
116-
while Pos(Delimiter, TmpInStr) > 0 do
117-
begin
118-
Words.Append(Copy(TmpInStr, 1, Pos(Delimiter, TmpInStr) - 1));
119-
Delete(TmpInStr, 1, Pos(Delimiter, TmpInStr));
120-
end;
121-
Words.Append(TmpInStr);
122-
end;
202+
Result := SysUtils.StringReplace(
203+
S, '&', SysUtils.EmptyStr, [SysUtils.rfReplaceAll]
204+
);
123205
end;
124206

125207
end.
126-

0 commit comments

Comments
 (0)