2015-05-10 16 views
5

Làm thế nào để một mảng chuỗi được chuyển thành chuỗi (Với dấu tách char)? Tôi có nghĩa là, có một số chức năng hệ thống tôi có thể sử dụng thay vì viết chức năng của riêng tôi?Làm thế nào để nối chuỗi các phần tử chuỗi thành một chuỗi

+2

Phiên bản Delphi nào? –

+0

@KenWhite: Phiên bản là Delphi2007 – Hwau

+0

Bạn có thể sử dụng TStringList với Dấu phân tách. Hoặc bạn có thể viết cho bạn chức năng riêng. Tôi sẽ tránh TStringList. Không cần phải làm một ví dụ cho việc này. –

Trả lời

4

Vì bạn đang sử dụng Delphi 2007 bạn phải làm điều đó bạn tự:

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; 

Đơn giản chỉ cần đi qua mảng và concat nó với seperator của bạn.

Và một ví dụ thử nghiệm nhỏ:

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

Tôi đã viết chức năng của riêng mình! Cảm ơn bạn đã đề xuất! – Hwau

+0

Không lý tưởng về mặt tốc độ –

2

Trong delphi cho .NET, bạn có thể sử dụng chức năng khuôn khổ Join, trong khi nếu bạn không muốn dựa vào khuôn khổ NET thì bạn có thể liên kết các thư viện mã nguồn mở JCL: hãy nhìn vào các IJclStringList interface của thư viện .

JclStringList.Join(','); 

Nếu như ai đó đề nghị trong ý kiến ​​bạn chỉ có thể sử dụng một TStringList theo cách này:

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

Lưu ý rằng phiên bản mới nhất của Delphi XES (kể từ XE3 nếu tôi cũng nhớ) có một TStringHelper lớp bổ sung phương thức Join vào lớp Chuỗi:

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

Bạn muốn quá tải 'Tham gia' chấp nhận một mảng mở của' chuỗi'. Tất nhiên, 'Tham gia', là một phần của trình trợ giúp chuỗi, được thực hiện rất kém. Phiên bản 'IEnumerable ' bị hỏng cho đến XE8 và hiệu quả kém. Thật bực bội khi chất lượng RTL gần đây của Emba quá kém. –

3

Câu trả lời được chấp nhận không phải là lý tưởng về mặt tốc độ, đặc biệt là nếu có nhiều chủ đề được sử dụng. Cách tiếp cận này nhanh gấp 3 lần trên lõi đơn, và cân đối tốt trên 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; 

Tốc độ kiểm tra:

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. 

Kết quả: trên một quad-core CPU JoinStrings là 12x nhanh hơn.

StrArrayJoin 1 thread: 55 
JoinStrings 1 thread: 184 
StrArrayJoin 4 threads: 58 
JoinStrings 4 threads: 713 
Các vấn đề liên quan