Recent

Author Topic: [SOLVED] Filter duplicate values in TStringList name/value strings  (Read 727 times)

maurobio

  • Hero Member
  • *****
  • Posts: 623
  • Ecology is everything.
    • GitHub
Dear ALL,

I have a list of strings as name/value pairs delimited by the '|' character, in the form:

Code: Pascal  [Select][+][-]
  1. SL[0] := 'S1|This is a string';
  2. SL[1] := 'S2|This is a string';
  3. SL[2] := 'S3|This is another string';

I want to filter this list by ignoring the duplicate values, so that I get only the contents of SL{0] and SL[2].

I tried using

Code: Pascal  [Select][+][-]
  1. if (Pos('This is a string', SL.Strings[i]) <> 0) then ...

but to no avail.

Any hints?

Thanks in advance!

Best regards,
« Last Edit: June 29, 2023, 01:45:49 am by maurobio »
UCSD Pascal / Burroughs 6700 / Master Control Program
Delphi 7.0 Personal Edition
Lazarus 2.0.12 - FPC 3.2.0 on GNU/Linux Mint 19.1, Lubuntu 18.04, Windows XP SP3, Windows 7 Professional, Windows 10 Home

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Filter duplicate values in TStringList name/value strings
« Reply #1 on: June 28, 2023, 04:38:49 pm »
Any hints?
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$LONGSTRINGS ON}
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses SysUtils, Classes;
  6.  
  7. const
  8.   CData = 'S1|This is a string' + LineEnding +
  9.     'S2|This is a string' + LineEnding +
  10.     'S3|This is another string';
  11. var
  12.   L, Values: TStringList;
  13.   i: Integer;
  14.   V: string;
  15. begin
  16.   L := TStringList.Create;
  17.   try
  18.     L.Text := CData;
  19.     L.NameValueSeparator := '|';
  20.     Values := TStringList.Create;
  21.     try
  22.       Values.Sorted := True;
  23.       for i := 0 to L.Count - 1 do
  24.       begin
  25.         V := L.ValueFromIndex[i];
  26.         if Values.IndexOf(V) < 0 then
  27.         begin
  28.           Writeln(L[i]);
  29.           Values.Append(V);
  30.         end;
  31.       end;
  32.     finally
  33.       Values.Free;
  34.     end;
  35.   finally
  36.     L.Free;
  37.   end;
  38.   Readln;
  39. end.

maurobio

  • Hero Member
  • *****
  • Posts: 623
  • Ecology is everything.
    • GitHub
Re: Filter duplicate values in TStringList name/value strings
« Reply #2 on: June 28, 2023, 04:46:38 pm »
Hi, @ASerge!

Thank you very much!

Just a further question: has the list really to be sorted? And, if so, should the Find method be invoked instead IndexOf? Just curious.

With warmest regards,
UCSD Pascal / Burroughs 6700 / Master Control Program
Delphi 7.0 Personal Edition
Lazarus 2.0.12 - FPC 3.2.0 on GNU/Linux Mint 19.1, Lubuntu 18.04, Windows XP SP3, Windows 7 Professional, Windows 10 Home

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Filter duplicate values in TStringList name/value strings
« Reply #3 on: June 28, 2023, 04:47:58 pm »
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses
  4.   SysUtils, Classes;
  5.  
  6. var
  7.   sl: TStringList;
  8.   i: Integer;
  9. begin
  10.   sl := TStringList.Create;
  11.   try
  12.     sl.Sorted := True;
  13.     sl.Duplicates := dupIgnore;
  14.     sl.Add('Test 1');
  15.     sl.Add('Test 2');
  16.     sl.Add('Test 1');
  17.     for i := 0 to Pred(sl.Count) do
  18.       WriteLn(sl[i]);
  19.     ReadLn;
  20.   finally
  21.     sl.Free;
  22.   end;
  23. end.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

ASerge

  • Hero Member
  • *****
  • Posts: 2223
Re: Filter duplicate values in TStringList name/value strings
« Reply #4 on: June 28, 2023, 04:55:41 pm »
Just a further question: has the list really to be sorted? And, if so, should the Find method be invoked instead IndexOf? Just curious.
Sorting is just to speed up.
The Find method requires one more parameter. Therefore, the IndexOf method is more convenient.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2010
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Filter duplicate values in TStringList name/value strings
« Reply #5 on: June 28, 2023, 05:02:31 pm »
Just a further question: has the list really to be sorted? And, if so, should the Find method be invoked instead IndexOf? Just curious.
Sorting is just to speed up.
The Find method requires one more parameter. Therefore, the IndexOf method is more convenient.
Find only works on sorted lists AFAIK, IndexOf chooses internal what way to go.
Here in a unsorted way:
Code: Pascal  [Select][+][-]
  1. var
  2.   sl: TStringList;
  3.   i: Integer;
  4. begin
  5.   sl := TStringList.Create;
  6.   try
  7.     if sl.IndexOf('Test 1') = -1 then
  8.       sl.Add('Test 1');
  9.     if sl.IndexOf('Test 2') = -1 then
  10.       sl.Add('Test 2');
  11.     if sl.IndexOf('Test 1') = -1 then
  12.       sl.Add('Test 1');
  13.     for i := 0 to Pred(sl.Count) do
  14.       WriteLn(sl[i]);
  15.     ReadLn;
  16.   finally
  17.     sl.Free;
  18.   end;
  19. end.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

maurobio

  • Hero Member
  • *****
  • Posts: 623
  • Ecology is everything.
    • GitHub
Re: Filter duplicate values in TStringList name/value strings
« Reply #6 on: June 28, 2023, 08:45:44 pm »
Hi, @ASerge, @KodeZwerg,

Thanks a lot for your insightful suggestions and code.

KodeZwerg, using the Duplicates property has not worked for me (I have tried it before posting my question  ;)), because taken individually, the three strings in the list are different - only the key part (before the '|' character) makes them distinctive.

With warmest regards,

UCSD Pascal / Burroughs 6700 / Master Control Program
Delphi 7.0 Personal Edition
Lazarus 2.0.12 - FPC 3.2.0 on GNU/Linux Mint 19.1, Lubuntu 18.04, Windows XP SP3, Windows 7 Professional, Windows 10 Home

maurobio

  • Hero Member
  • *****
  • Posts: 623
  • Ecology is everything.
    • GitHub
Re: Filter duplicate values in TStringList name/value strings
« Reply #7 on: June 29, 2023, 01:45:33 am »
Hi,

ASerge code did the trick!

Thank you very much!

Best regards,
UCSD Pascal / Burroughs 6700 / Master Control Program
Delphi 7.0 Personal Edition
Lazarus 2.0.12 - FPC 3.2.0 on GNU/Linux Mint 19.1, Lubuntu 18.04, Windows XP SP3, Windows 7 Professional, Windows 10 Home

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Filter duplicate values in TStringList name/value strings
« Reply #8 on: June 29, 2023, 08:48:48 am »
Find only works on sorted lists AFAIK, IndexOf chooses internal what way to go.
Correct.
the Find-Method actually requires the List to be sorted (returns Error if List not sorted), while IndexOf for unsorted runs sequentially through it, for sorted it defers to Find.
Find uses a binary search
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

 

TinyPortal © 2005-2018