delphi - String.Split works strange when last value is empty -


i'd split string array works bad when last "value" empty. see example please. bug or feature? there way how use function without workarounds?

var   arr: tarray<string>;    arr:='a;b;c'.split([';']); //length of array = 3, it's ok   arr:='a;b;c;'.split([';']); //length of array = 3, expect 4   arr:='a;b;;c'.split([';']); //length of array = 4 since empty value inside   arr:=('a;b;c;'+' ').split([';']); //length of array = 4 (primitive workaround space) 

this behaviour can't changed. there's no way customise how split function works. suspect you'll need provide own split implementation. michael erikkson helpfully points out in comment system.strutils.splitstring behaves in manner desire.

the design seems me poor. instance

length('a;'.split([';'])) = 1 

and yet

length(';a'.split([';'])) = 2 

this asymmetry clear indication of poor design. it's astonishing testing did not identify this.

the fact design suspect means may worth submitting bug report. i'd expect denied since change impact existing code. never know.

my recommendations:

  1. use own split implementation performs require.
  2. submit bug report.

whilst system.strutils.splitstring want, performance not great. not matter. in case should use it. however, if performance matters, offer this:

{$apptype console}  uses   system.sysutils, system.diagnostics, system.strutils;  function mysplit(const s: string; separator: char): tarray<string>; var   i, itemindex: integer;   len: integer;   separatorcount: integer;   start: integer; begin   len := length(s);   if len=0 begin     result := nil;     exit;   end;    separatorcount := 0;   := 1 len begin     if s[i]=separator begin       inc(separatorcount);     end;   end;    setlength(result, separatorcount+1);   itemindex := 0;   start := 1;   := 1 len begin     if s[i]=separator begin       result[itemindex] := copy(s, start, i-start);       inc(itemindex);       start := i+1;     end;   end;   result[itemindex] := copy(s, start, len-start+1); end;  const   inputstring = 'asdkjhasd,we1324,wqweqw,qweqlkjh,asdqwe,qweqwe,asdasdqw';  var   i: integer;   stopwatch: tstopwatch;  const   count = 3000000;  begin   stopwatch := tstopwatch.startnew;   := 1 count begin     inputstring.split([',']);   end;   writeln('string.split: ', stopwatch.elapsedmilliseconds);    stopwatch := tstopwatch.startnew;   := 1 count begin     system.strutils.splitstring(inputstring, ',');   end;   writeln('strutils.splitstring: ', stopwatch.elapsedmilliseconds);    stopwatch := tstopwatch.startnew;   := 1 count begin     mysplit(inputstring, ',');   end;   writeln('mysplit: ', stopwatch.elapsedmilliseconds); end. 

the output of 32 bit release build xe7 on e5530 is:

 string.split: 2798 strutils.splitstring: 7167 mysplit: 1428 

Comments

Popular posts from this blog

javascript - gulp-nodemon - nodejs restart after file change - Error: listen EADDRINUSE events.js:85 -

Fatal Python error: Py_Initialize: unable to load the file system codec. ImportError: No module named 'encodings' -

javascript - oscilloscope of speaker input stops rendering after a few seconds -