Results 1 to 6 of 6

Thread: TStringList: simpel of pairs

  1. #1
    Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    98

    Question TStringList: simpel of pairs

    Ik ben bezig met enkele functies die van twee TStringLists een doorsnede maken of een controle of het een subset betreft.
    Nu kom ik erachter dat ik simpele lijsten heb maar ook lijsten met naam en waarde paren...
    Is de enige manier om achteraf, in een functie, hier onderscheid in te maken controle op '=' zoals in onderstaand voorbeeld?

    Code:
    function IsIntersection(var slSource: TStringList; sDest: string): Boolean; overload;
    //***********************************************************************************
    var
      slDest: TStringList;
      i: Integer;
      bPairs: Boolean;
    
    begin
      // 14/09/2018
    
      // Initialiseren
      Result := False;
      bPairs := Pos('=',slSource[0]) <> 0;
    
      slDest := TStringList.Create;
      slDest.Delimiter := ',';
      slDest.DelimitedText := sDest;
    
      // Controleren of minstens  een waardes van slSource ook in slDest voorkomt
      // afbreken zodra een waarde gevonden wordt
      for i := 0 to slDest.Count - 1 do
      begin
        if bPairs then
          begin
            if slSource.IndexOfName(slDest[i]) <> -1 then
              begin
                Result := True;
                Break;
              end;
          end
        else
          begin
            if slSource.IndexOf(slDest[i]) <> -1 then
              begin
                Result := True;
                Break;
              end;
          end
      end;
    
      // Vrijgeven StringList
      slDest.Free;
    
      // IsIntersection
    end;
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  2. #2
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,274
    Echt betrouwbaar is jouw controle niet: een ini-bestand (deze bevat altijd "name=value"-paren) zal namelijk falen,
    omdat de eerste waarde op z'n vroegst op de tweede regel staat (na de eerste [Section])... als deze lijst al netjes
    opgebouwd is (een echte harde norm is er namelijk niet).

    Maar eigenlijk is het helemaal niet spannend of het een "name=value" lijst is of niet: jouw functie (of althans de
    naam suggereert dat) gaat alleen op zoek naar een bepaalde overeenkomst (in dit geval een deel hetzelfde is)
    tussen twee stringlists.
    Wat nu als de naam wel overeenkomt en de waarde niet, is dit dan toch gelijk (want dat zegt je code, maar dan
    klopt je naam en/of beschrijving niet helemaal).
    Verder klopt je code niet: je code vindt het al goed als hij slechts één match gevonden heeft; een intersection
    betekent juist dat alle waarden uit sDest in slSource moeten zitten.

    Waarom heeft de functie trouwens als eerste parameter een TStrings-afgeleide (en waarom is dit een "Var"?) en
    de tweede een gewone string?
    Waar is je try..finally..end-blok voor slDest?
    Waarom controleer je binnen de loop of bPairs true is, deze verandert toch niet meer?
    Last edited by VideoRipper; 14-Sep-18 at 14:41.
    TMemoryLeak.Create(Nil);

  3. #3
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,274
    De specificaties zijn te onzeker, maar dit zou ik er ongeveer van maken:
    Delphi Code:
    1. uses
    2.   Classes, SysUtils;
    3.  
    4. type
    5.   TStringsHelper = class helper for TStrings
    6.     function IsIntersection(const ADest: TStrings): Boolean; overload;
    7.     function IsIntersection(const ADest: string): Boolean; overload;
    8.   end;
    9.  
    10. implementation
    11.  
    12. { TStringsHelper }
    13.  
    14. function TStringsHelper.IsIntersection(const ADest: TStrings): Boolean;
    15. var
    16.   C: Integer;
    17.   I: Integer;
    18.   P: Boolean;
    19. begin
    20.   P := False;
    21.   I := 0;
    22.   while (not P) and
    23.         (I < Count) do
    24.     if Pos('=', Strings[I]) > 1 then
    25.       P := True
    26.     else
    27.       Inc(I);
    28.  
    29. // Bovenstaande kun je natuurlijk ook herschrijven als: P := Pos('=', Text) > 0;
    30.  
    31.   C := 0;
    32.   I := 0;
    33.   Result := False;
    34.   if P then
    35.     while (I < ADest.Count) do
    36.     begin
    37.       if IndexOfName(ADest.Names[I]) >= 0 then
    38.         Inc(C);
    39.       Inc(I);
    40.     end
    41.   else
    42.     while (I < ADest.Count) do
    43.     begin
    44.       if IndexOf(ADest[I]) >= 0 then
    45.         Inc(C);
    46.       Inc(I);
    47.     end;
    48.   Result := C = ADest.Count;
    49. end;
    50.  
    51. function TStringsHelper.IsIntersection(const ADest: string): Boolean;
    52. var
    53.   SL: TStringList;
    54. begin
    55.   SL := TStringList.Create;
    56.   try
    57.     SL.Delimiter := ',';
    58.     SL.DelimitedText := ADest;
    59.     Result := IsIntersection(SL);
    60.   finally
    61.     SL.Free;
    62.   end;
    63. end;
    Last edited by VideoRipper; 14-Sep-18 at 14:40.
    TMemoryLeak.Create(Nil);

  4. #4
    Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    98
    Hallo VideoRipper,

    Sorry voor de late reactie en bedankt voor het meedenken!

    Ik moet controleren of een bepaald belastingtype onderdeel uitmaakt van een set.
    Elk belastingtype heeft een vermenigvuldigingsfactor. Deze staan in slSource:
    DL=1.2
    LL=1.0
    TL=1.2
    Wix=1.0
    Wiy=1.0
    WixTL=1.0
    WiyTL=1.0

    De sets heb ik gedefinieerd als const, dit zijn meerdere sets
    Fixed_sec_LT = 'EQix,EQiy,Wix,Wiy';
    Secundary_LT = 'EQixTL,EQiyTL,WixTL,WiyTL';

    Deze string wordt binnen de routine opgesplitst in een "simpele" StringList.

    Wanneer één van de belastingtypes deel uitmaakt van de set is er al een intersectie en moet een bepaalde set berekeningen worden uitgevoerd. Wanneer alle waaardes van sDest in slSource zitten heb je te maken met een subset...

    Ik heb geen try except ingebouwd omdat de StringList en de string van tevoren helemaal gecontroleerd zijn. Ik zal wel een try finally inbouwen voor de slDest.Free.

    De "var" is niet nodig.
    bPairs veranderd niet binnen de loop maar ik programeer graag heel expliciet met veel commentaar zodat de code ook leesbaar is voor mijn colega's engineers.

    Op enkele ander plaatsen in de code wordt het belastingtype aangeboden zonder vermenigvuldigingsfactor en dus als "simpele" StringList.
    Voor een generieke IsIntersection() moet ik dus controleren op de aanwezigheid van het '=' teken. Een controle op het eerste element van slSource is al voldoende. Afhankelijk van het "=" teken moet ik IndexOfName of IndexOf toepassen omdat slDest, gegenereerd uit sDest, nooit factoren bevat.


    Het komt er dus op neer dat je moet controleren op het "=" teken. Ik dacht dat ik mss een propertie of iets dergelijks over het hoofd had gezien...


    Groetjes
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

  5. #5
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,274
    Quote Originally Posted by DaSteelMan View Post
    heb je te maken met een subset...
    Inderdaad, je hebt gelijk.

    Quote Originally Posted by DaSteelMan View Post
    Het komt er dus op neer dat je moet controleren op het "=" teken.
    Strikt genomen moet je controleren op het "NameValueSeparator"-teken, maar ik heb nog nooit gezien
    dat iemand deze anders heeft ingesteld dan "=".
    TMemoryLeak.Create(Nil);

  6. #6
    Member DaSteelMan's Avatar
    Join Date
    Apr 2004
    Location
    Eys (LimboLand)
    Posts
    98
    Top!
    Achtbanen!
    Soms ben je er helemaal van ondersteboven...

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •