2015-05-10 64 views
5

應該如何將字符串數組轉換爲字符串(使用分隔符char)?我的意思是,有沒有我可以使用的一些系統功能,而不是編寫我自己的功能?如何將字符串元素的數組連接成字符串

+2

什麼德爾福版本? –

+0

@KenWhite:版本是Delphi2007 – Hwau

+0

您可以使用帶分隔符的TStringList。或者你可以寫你自己的功能。我會迴避TStringList。無需爲此創建實例。 –

回答

4

由於您使用德爾福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; 

簡單地遍歷數組,並與您的分隔符Concat的它。

和一個小試驗例:

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Caption :=StrArrayJoin(['This', 'is', 'a', 'test'], ' '); 
end; 
+1

我寫了我自己的功能!感謝您的建議! – Hwau

+0

在速度方面不理想 –

2

在delphi for .NET中,您可以使用框架Join函數,而如果您不想依賴.NET框架,則可以鏈接開源JCL庫:查看庫的IJclStringList interface

JclStringList.Join(','); 

否則有人在意見建議你可以簡單地用TStringList中這樣說:

arrayList.Delimiter := ','; 
arrayList.QuoteChar := ''; 
joinedArray := arrayList.DelimitedText; 

需要注意的是德爾福XES的最新版本(因爲XE3如果我清楚地記得)有TStringHelper類,其將所述Join方法String類

class function Join(const Separator: string; const Values: 
IEnumerator<string>): string; overload; static; 
+1

你想要接受一個開放的'string'數組的'Join'重載。當然,作爲字符串助手的一部分的「Join」實現得非常糟糕。 'IEnumerable '版本在XE8之前破解,效率很差。 Emba最近的RTL質量非常差,令人沮喪。 –

3

接受的答案是沒有在速度方面理想的,尤其是在使用多個線程。這種方法在單核上速度提高了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 
相關問題