Autor Beitrag
n-regen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 202
Erhaltene Danke: 2



BeitragVerfasst: So 28.02.10 19:30 
Hallo!

Ich habe mir gerade eine Funktion gebastelt, die einen String anhand eines Trennzeichens in drei Teile zerlegt, eventuelle Anführungszeichen an Anfang und Ende der Teilstrings entfernt und diese dann als record zurückgibt.
Kann man die Funktion noch irgendwie schneller machen?

ausblenden volle Höhe Delphi-Quelltext
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:
type
  TExplodedString = record
    value1:string;
    value2:string;
    value3:string;
  end;

function explode(inputstr, separator: string):TExplodedString;
var ps,dest: integer;
begin
  dest := 0;
  result.value1 := '';
  result.value2 := '';
  result.value3 := '';
  for ps := 1 to length(inputstr) do begin
    if inputstr[ps] = separator
    then inc(dest)
    else begin
      case dest of
        0: result.value1 := result.value1 + inputstr[ps];
        1: result.value2 := result.value2 + inputstr[ps];
        2: result.value3 := result.value3 + inputstr[ps];
      end;
    end;
  end;
  if result.value1[1] = '"'
  then begin
    result.value1 := copy(result.value1, 2, length(result.value1)-2);
    result.value2 := copy(result.value2, 2, length(result.value2)-2);
    result.value3 := copy(result.value3, 2, length(result.value3)-2);
  end;
end;


Zuletzt bearbeitet von n-regen am So 28.02.10 21:02, insgesamt 1-mal bearbeitet
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 28.02.10 19:43 
Ungetestet, aber so oder so ähnlich könnte es gehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
type
  TExplodedString = array[0..2of string;

function explode(inputstr, separator: string):TExplodedString;
var
  i, p: integer;
  exstr: string;
begin
  for i := 0 to 2 do
  begin
    p := pos(inpustr, separator);
    exstr[i] := copy(inputstr, 1, p-1);
    inputstr := copy(inputstr, p+length(separator));
  end;
  return exstr;
end;

Gibt es sowas wie NextPos() in Delphi?


Zuletzt bearbeitet von F34r0fTh3D4rk am So 28.02.10 19:52, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 28.02.10 19:48 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Gibt es sowas wie NextPos() in Delphi?
Meinst du Suche in der Delphi-Reference POSEX?
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 28.02.10 19:51 
Delphi scheint leider nicht so eine tolle API zu haben wie Java*, deshalb hab ichs auf die Schnelle nicht gefunden ;)

Dann ist es ungefähr so (ungetestet):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function explode(inputstr, separator: string):TExplodedString;
var
  i, p, last: integer;
  exstr: TExplodedString;
begin
  last = 1;
  for i := 0 to 2 do
  begin
    p := posex(inpustr, separator, last);
    exstr[i] := copy(inputstr, 1, p-1);
    last := p+length(separator); 
  end;
  result := exstr;
end;

*String, ja OOP ist schon was feines ;)

EDIT: return durch result := ersetzt.


Zuletzt bearbeitet von F34r0fTh3D4rk am So 28.02.10 21:08, insgesamt 5-mal bearbeitet
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 28.02.10 19:59 
Wenn zuwenige Trennzeichen enthalten ist, gibt Copy nen Leerstring zurück für den letzten Teilstring

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
n-regen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 202
Erhaltene Danke: 2



BeitragVerfasst: So 28.02.10 21:02 
So, ich habe user profile iconF34r0fTh3D4rks Vorschlag von halb-C nach Delphi übersetzt und überarbeitet:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function TForm1.explode(inputstr, separator: string):TExplodedString;
var
  i, p, last: integer;
begin
  last := 1;
  for i := 0 to 1 do
  begin
    p := posex(separator, inputstr, last);
    result[i] := copy(inputstr, last, p-last);
    last := p+length(separator);
  end;
  result[2] := copy(inputstr, last, length(inputstr)-(last-1));
  if result[0][1] = '"' then begin
    result[0] := copy(result[0], 2, length(result[0])-2);
    result[1] := copy(result[1], 2, length(result[1])-2);
    result[2] := copy(result[2], 2, length(result[2])-2);
  end;
end;

Die Funktion ist zwar immer noch (oder schon wieder) ziemlich langsam, aber sie funktioniert.
Vielen Dank euch allen!
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 28.02.10 21:08 
Sry wegen der fremdartigen Syntax :lol: , aber ich benutze seit Jahren kein Delphi mehr ;)

Eine Frage: Wozu ist das?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  if result[0][1] = '"' then begin
    result[0] := copy(result[0], 2, length(result[0])-2);
    result[1] := copy(result[1], 2, length(result[1])-2);
    result[2] := copy(result[2], 2, length(result[2])-2);
  end;

Und was hat es mit dem '"' aufsich?
n-regen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 202
Erhaltene Danke: 2



BeitragVerfasst: So 28.02.10 21:26 
Der Teil soll Anführungszeichen am Anfang und Ende der Teilstrings rausfiltern.
Man könnte ihn auch noch verkürzen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  if result[0][1] = '"' then begin
    for i := 0 to 2
    do result[i] := copy(result[i], 2, length(result[i])-2);
  end;


Ach ja: ' leitet einen String ein. '"' ist also ein String, der nur ein Anführungszeichen enthält.
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: So 28.02.10 21:49 
user profile iconn-regen hat folgendes geschrieben Zum zitierten Posting springen:
Der Teil soll Anführungszeichen am Anfang und Ende der Teilstrings rausfiltern.
Man könnte ihn auch noch verkürzen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  if result[0][1] = '"' then begin
    for i := 0 to 2
    do result[i] := copy(result[i], 2, length(result[i])-2);
  end;



Ohne jetzt den restlichen Code genauer analysiert zu haben: Bist Du sicher, dass Result[0] niemals ein Leerstring sein kann? Wenn doch, knallt das da:

ausblenden Delphi-Quelltext
1:
if result[0][1] = '"' then					


twm
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 28.02.10 22:42 
user profile iconn-regen hat folgendes geschrieben Zum zitierten Posting springen:
Ach ja: ' leitet einen String ein. '"' ist also ein String, der nur ein Anführungszeichen enthält.

Ich weiß wie Strings in Delphi funktionieren :). Ich habe mich nur gewundert, was etwas so spezielles in einer allgemeinen explode Methode zu suchen hat.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 28.02.10 22:47 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe mich nur gewundert, was etwas so spezielles in einer allgemeinen explode Methode zu suchen hat.
Eine allgemeine Explode-Funktion mit exakt drei Output-Einträgen :mrgreen: ? Das mit den Anführungszeichen hätte ich heute aber gut gebrauchen können ;) ...

_________________
>λ=
n-regen Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 202
Erhaltene Danke: 2



BeitragVerfasst: Mo 01.03.10 01:30 
user profile icondummzeuch hat folgendes geschrieben Zum zitierten Posting springen:
Ohne jetzt den restlichen Code genauer analysiert zu haben: Bist Du sicher, dass Result[0] niemals ein Leerstring sein kann? Wenn doch, knallt das da:
ausblenden Delphi-Quelltext
1:
if result[0][1] = '"' then					
Das könnte wirklich problematisch werden.
Welche Alternative ist da schneller?
ausblenden Delphi-Quelltext
1:
if (result[0][1] <> ''and (result[0][1] = '"'then					
(Delphi würde doch nach dem ersten Vergleich aufhören, wenn er FALSE zurückgibt, oder?)
oder
ausblenden Delphi-Quelltext
1:
if pos('"', result[0][1]) = 1 then					
aksdb
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 29
Erhaltene Danke: 1

Windows 7, ArchLinux
D7 Prof, Kylix 3, Lazarus
BeitragVerfasst: Mo 01.03.10 02:36 
Spricht denn was dagegen, eine TStringList mit .Delimiter und .DelimitedText zu benutzen?
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Mo 01.03.10 10:29 
user profile iconaksdb hat folgendes geschrieben Zum zitierten Posting springen:
Spricht denn was dagegen, eine TStringList mit .Delimiter und .DelimitedText zu benutzen?
Ja - die Geschwindigkeit ;)

Guck mal in die DP, da wurde sowas schonmal "durchoptimiert" www.delphipraxis.net...ic98278,0,asc,0.html ;)
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5284
Erhaltene Danke: 27

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: Mo 01.03.10 12:03 
user profile iconn-regen hat folgendes geschrieben Zum zitierten Posting springen:
user profile icondummzeuch hat folgendes geschrieben Zum zitierten Posting springen:
Ohne jetzt den restlichen Code genauer analysiert zu haben: Bist Du sicher, dass Result[0] niemals ein Leerstring sein kann? Wenn doch, knallt das da:
ausblenden Delphi-Quelltext
1:
if result[0][1] = '"' then					
Das könnte wirklich problematisch werden.
Welche Alternative ist da schneller?
ausblenden Delphi-Quelltext
1:
if (result[0][1] <> ''and (result[0][1] = '"'then					
(Delphi würde doch nach dem ersten Vergleich aufhören, wenn er FALSE zurückgibt, oder?)
oder
ausblenden Delphi-Quelltext
1:
if pos('"', result[0][1]) = 1 then					

Ich glaube, bevor man sich solche Fragen stellen muss, sollte man sich den Rest seines Codes nochmal genau angucken, um ausschließen zu können, dass die Geschwindigkeitsbremse nicht doch ganz woanders liegt. Wie es aussieht hast du ja nur vor, einen String in drei Teile zu zerlegen. Das wird nur dann zu einem Zeitproblem, wenn du das sehr häufig machst. Was ist der genaue Kontext, in dem du deine Funktion verwendest? Vielleicht lässt sich da einiges mehr herausholen.
tif
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46
Erhaltene Danke: 1

Winxxx
TP, BP, Delphi 1 - 2009
BeitragVerfasst: Mo 01.03.10 12:32 
Versteckt in der Unit HttpUtil gibt's noch (zumindest bei/ab 2009)

ausblenden Delphi-Quelltext
1:
function StringToStringArray(const str: stringconst delim: string): TStringDynArray;					


Ob die schneller ist weiss ich nicht, aber sie dampft den Quelltext auf eine Zeile ein.

Viel Erfolg
Tino