如何将字符串元素数组连接成一个字符串
How to concatenate array of string elements into a string
字符串数组应该如何转换成字符串(带分隔符char)?我的意思是,有没有我可以使用的系统函数而不是编写自己的函数?
在 delphi for .NET 中,您可以使用库的框架 Join function , while if you don't want to rely on the .NET framework then you can link the open source JCL library : take a look at the IJclStringList interface。
JclStringList.Join(',');
否则,正如有人在评论中建议的那样,您可以通过这种方式简单地使用 TStringList:
arrayList.Delimiter := ',';
arrayList.QuoteChar := '';
joinedArray := arrayList.DelimitedText;
请注意,最新版本的 Delphi XEs(如果我没记错的话,从 XE3 开始)有一个 TStringHelper class 添加了Join 方法到字符串 class :
class function Join(const Separator: string; const Values:
IEnumerator<string>): string; overload; static;
由于您使用的是 Delphi 2007,因此您必须自己动手:
function StrArrayJoin(const StringArray : array of string; const Separator : string) : string;
var
i : Integer;
begin
Result := '';
for i := low(StringArray) to high(StringArray) do
Result := Result + StringArray[i] + Separator;
Delete(Result, Length(Result), 1);
end;
只需遍历数组并将其与分隔符连接即可。
还有一个小测试例子:
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption :=StrArrayJoin(['This', 'is', 'a', 'test'], ' ');
end;
接受的答案在速度方面并不理想,尤其是在使用多线程的情况下。这种方法在单核上的速度提高了 3 倍,并且在 SMP 上的扩展性很好。
function JoinStrings(const s: array of string; Delimiter: Char): string;
var
i, c: Integer;
p: PChar;
begin
c := 0;
for i := 0 to High(s) do
Inc(c, Length(s[i]));
SetLength(Result, c + High(s));
p := PChar(Result);
for i := 0 to High(s) do begin
if i > 0 then begin
p^ := Delimiter;
Inc(p);
end;
Move(PChar(s[i])^, p^, SizeOf(Char)*Length(s[i]));
Inc(p, Length(s[i]));
end;
end;
速度测试:
program Project1;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, StrUtils, Classes;
function StrArrayJoin(const StringArray: array of string; const Separator: string) : string;
var
i : Integer;
begin
Result := '';
for i := low(StringArray) to high(StringArray) do
Result := Result + StringArray[i] + Separator;
Delete(Result, Length(Result), 1);
end;
function JoinStrings(const s: array of string; Delimiter: Char): string;
var
i, c: Integer;
p: PChar;
begin
c := 0;
for i := 0 to High(s) do
Inc(c, Length(s[i]));
SetLength(Result, c + High(s));
p := PChar(Result);
for i := 0 to High(s) do begin
if i > 0 then begin
p^ := Delimiter;
Inc(p);
end;
Move(PChar(s[i])^, p^, SizeOf(Char)*Length(s[i]));
Inc(p, Length(s[i]));
end;
end;
var
TestData: array of string;
type
TTestThread = class(TThread)
protected
Func: Boolean;
Count: Integer;
procedure Execute; override;
end;
procedure TTestThread.Execute;
var
dtStart: TDateTime;
i: Integer;
begin
dtStart := Now;
Count := 0;
repeat
for i := 1 to 1000 do
if Func then
JoinStrings(TestData, ';')
else
StrArrayJoin(TestData, ';');
InterlockedIncrement(Count);
until Now > dtStart + 1/86400;
end;
procedure TestSmp(CpuCount: Integer; Func: Boolean);
var
i, c: Integer;
Threads: array of TTestThread;
begin
SetLength(Threads, CpuCount);
for i := 0 to High(Threads) do begin
Threads[i] := TTestThread.Create(true);
Threads[i].Func := Func;
Threads[i].Resume;
end;
c := 0;
for i := 0 to High(Threads) do begin
Threads[i].WaitFor;
Inc(c, Threads[i].Count);
Threads[i].Free;
end;
WriteLn(c);
end;
procedure Init();
var
i: Integer;
begin
SetLength(TestData, 1000);
for i := 0 to High(TestData) do
TestData[i] := DupeString('x', Random(32));
end;
begin
try
Init();
Assert(StrArrayJoin(TestData, ';') = JoinStrings(TestData, ';'));
TestSmp(1, false);
TestSmp(1, true);
TestSmp(4, false);
TestSmp(4, true);
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
Readln;
end.
结果:在四核上 CPU JoinStrings 快 12 倍。
StrArrayJoin 1 thread: 55
JoinStrings 1 thread: 184
StrArrayJoin 4 threads: 58
JoinStrings 4 threads: 713
如果您使用的是更新版本的 Delphi,您可以使用 TStringHelper.Join
,请参阅:http://docwiki.embarcadero.com/Libraries/Sydney/en/System.SysUtils.TStringHelper.Join
Writeln(String.Join(',', ['String1', 'String2', 'String3']));
输出将是:String1,String2,String3
字符串数组应该如何转换成字符串(带分隔符char)?我的意思是,有没有我可以使用的系统函数而不是编写自己的函数?
在 delphi for .NET 中,您可以使用库的框架 Join function , while if you don't want to rely on the .NET framework then you can link the open source JCL library : take a look at the IJclStringList interface。
JclStringList.Join(',');
否则,正如有人在评论中建议的那样,您可以通过这种方式简单地使用 TStringList:
arrayList.Delimiter := ',';
arrayList.QuoteChar := '';
joinedArray := arrayList.DelimitedText;
请注意,最新版本的 Delphi XEs(如果我没记错的话,从 XE3 开始)有一个 TStringHelper class 添加了Join 方法到字符串 class :
class function Join(const Separator: string; const Values:
IEnumerator<string>): string; overload; static;
由于您使用的是 Delphi 2007,因此您必须自己动手:
function StrArrayJoin(const StringArray : array of string; const Separator : string) : string;
var
i : Integer;
begin
Result := '';
for i := low(StringArray) to high(StringArray) do
Result := Result + StringArray[i] + Separator;
Delete(Result, Length(Result), 1);
end;
只需遍历数组并将其与分隔符连接即可。
还有一个小测试例子:
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption :=StrArrayJoin(['This', 'is', 'a', 'test'], ' ');
end;
接受的答案在速度方面并不理想,尤其是在使用多线程的情况下。这种方法在单核上的速度提高了 3 倍,并且在 SMP 上的扩展性很好。
function JoinStrings(const s: array of string; Delimiter: Char): string;
var
i, c: Integer;
p: PChar;
begin
c := 0;
for i := 0 to High(s) do
Inc(c, Length(s[i]));
SetLength(Result, c + High(s));
p := PChar(Result);
for i := 0 to High(s) do begin
if i > 0 then begin
p^ := Delimiter;
Inc(p);
end;
Move(PChar(s[i])^, p^, SizeOf(Char)*Length(s[i]));
Inc(p, Length(s[i]));
end;
end;
速度测试:
program Project1;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils, StrUtils, Classes;
function StrArrayJoin(const StringArray: array of string; const Separator: string) : string;
var
i : Integer;
begin
Result := '';
for i := low(StringArray) to high(StringArray) do
Result := Result + StringArray[i] + Separator;
Delete(Result, Length(Result), 1);
end;
function JoinStrings(const s: array of string; Delimiter: Char): string;
var
i, c: Integer;
p: PChar;
begin
c := 0;
for i := 0 to High(s) do
Inc(c, Length(s[i]));
SetLength(Result, c + High(s));
p := PChar(Result);
for i := 0 to High(s) do begin
if i > 0 then begin
p^ := Delimiter;
Inc(p);
end;
Move(PChar(s[i])^, p^, SizeOf(Char)*Length(s[i]));
Inc(p, Length(s[i]));
end;
end;
var
TestData: array of string;
type
TTestThread = class(TThread)
protected
Func: Boolean;
Count: Integer;
procedure Execute; override;
end;
procedure TTestThread.Execute;
var
dtStart: TDateTime;
i: Integer;
begin
dtStart := Now;
Count := 0;
repeat
for i := 1 to 1000 do
if Func then
JoinStrings(TestData, ';')
else
StrArrayJoin(TestData, ';');
InterlockedIncrement(Count);
until Now > dtStart + 1/86400;
end;
procedure TestSmp(CpuCount: Integer; Func: Boolean);
var
i, c: Integer;
Threads: array of TTestThread;
begin
SetLength(Threads, CpuCount);
for i := 0 to High(Threads) do begin
Threads[i] := TTestThread.Create(true);
Threads[i].Func := Func;
Threads[i].Resume;
end;
c := 0;
for i := 0 to High(Threads) do begin
Threads[i].WaitFor;
Inc(c, Threads[i].Count);
Threads[i].Free;
end;
WriteLn(c);
end;
procedure Init();
var
i: Integer;
begin
SetLength(TestData, 1000);
for i := 0 to High(TestData) do
TestData[i] := DupeString('x', Random(32));
end;
begin
try
Init();
Assert(StrArrayJoin(TestData, ';') = JoinStrings(TestData, ';'));
TestSmp(1, false);
TestSmp(1, true);
TestSmp(4, false);
TestSmp(4, true);
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
Readln;
end.
结果:在四核上 CPU JoinStrings 快 12 倍。
StrArrayJoin 1 thread: 55
JoinStrings 1 thread: 184
StrArrayJoin 4 threads: 58
JoinStrings 4 threads: 713
如果您使用的是更新版本的 Delphi,您可以使用 TStringHelper.Join
,请参阅:http://docwiki.embarcadero.com/Libraries/Sydney/en/System.SysUtils.TStringHelper.Join
Writeln(String.Join(',', ['String1', 'String2', 'String3']));
输出将是:String1,String2,String3