Recent

Author Topic: TStringList.Find not working on FPC 3.0.0 (solved)  (Read 4844 times)

karlsson

  • Newbie
  • Posts: 4
TStringList.Find not working on FPC 3.0.0 (solved)
« on: February 26, 2016, 09:26:07 pm »
Hi!

I tried execute this simple code. It works with FPC 2.6.4 but not 3.0.0. Is that bug or I am doing something wrong?
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. var l : TStringList;
  3.     i : integer;
  4. begin
  5. l := TStringList.Create;
  6. l.add('1');
  7. l.add('2');
  8. l.add('3');
  9. l.add('4');
  10. showmessage(booltostr(l.Find('3',i))); //not found !
  11. showmessage(inttostr(i)); //always return index 1
  12. end;
« Last Edit: February 26, 2016, 11:10:26 pm by karlsson »

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: tstringlist find not working on FPC 3.0.0
« Reply #1 on: February 26, 2016, 09:34:07 pm »
You forgot:
Code: Pascal  [Select][+][-]
  1. l.Sorted := true;
First lines in TStringList.Find():
Code: Pascal  [Select][+][-]
  1.   if Not Sorted then
  2.     exit;

B.T.W. This is documented:
http://www.freepascal.org/docs-html/rtl/classes/tstringlist.find.html
Quote
  • Use this method only on sorted lists. For unsorted lists, use TStringList.IndexOf instead
  • Find uses a binary search method to locate the string
« Last Edit: February 26, 2016, 09:36:23 pm by rvk »

karlsson

  • Newbie
  • Posts: 4
Re: tstringlist find not working on FPC 3.0.0 (solved)
« Reply #2 on: February 26, 2016, 11:09:46 pm »
Thank You!
Problem began from another project, which was created FPC 2.6.4. There was list.sort(). In FPC 3.0.0 seems this does not do nothing, even if before list.sorted is set true. I set list.sorted to true and this fix the problem.

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: TStringList.Find not working on FPC 3.0.0 (solved)
« Reply #3 on: February 26, 2016, 11:28:10 pm »
TStringList.Sort does not set the Sorted-property to true. It sorts the stringlist once. Because there could be elements added later it's not certain that the list will remain sorted. That's why .Find() (in FPC 3.0) doesn't work. After Sorted is set to true it is certain the list is sorted.

You are correct that FPC 2.6.4 did not check for Sorted is true BUT if the list was not sorted it could have unexpected/wrong results (because it did a binary search on a "maybe" unsorted list). That's why the check on Sorted=true was build in.
 
B.T.W. It's always better to use IndexOf() because that will use IndexOf() on an unsorted list and Find() on a sorted list so the best method is always used. See the implementation of IndexOf():
Code: Pascal  [Select][+][-]
  1. Function TStringList.IndexOf(const S: string): Integer;
  2. begin
  3.   If Not Sorted then
  4.     Result:=Inherited indexOf(S)
  5.   else
  6.     // faster using binary search...
  7.     If Not Find (S,Result) then
  8.       Result:=-1;
  9. end;
« Last Edit: February 26, 2016, 11:30:33 pm by rvk »

apexcol

  • Jr. Member
  • **
  • Posts: 54
Re: TStringList.Find not working on FPC 3.0.0 (solved)
« Reply #4 on: August 11, 2017, 12:23:28 pm »
I have problems with TStrinList...

Code: Pascal  [Select][+][-]
  1. procedure TotaliseByNames;
  2. var
  3.         SL : TStringList;
  4.         I1, I3 : integer;
  5.         vElement: TDOMElement;
  6.         vInputList: TDOMNodeList;
  7. begin   // vInputList is out of scope but is another TStringList
  8.         SL := TStringList.Create;
  9.         SL.Sorted := true;
  10.         for I1 := 0 to pred(vInputList.Count) do begin
  11.                 vElement := vInputList[I1];
  12.                 SL.Find(vElement['name'], I3);
  13.                 if I3 = -1 then  // does not exist then
  14.                         SL.AddObject(vElement['name'], vElement) // create the first
  15.                 else begin
  16.                         {some other code that modifies vElement with aritmethic operations...}
  17.                 end;
  18.         FAnotherList.Assign(SL);               
  19. end;
  20.  

on the Finding it breaks the program...

Also I tried with IndexOf and it shows a number like 8261232 instead of -1,
I checked the code inside and it has some things to fix, for example
in stringl.inc line 936 instead of Result:=Result+1; it must be inc(Result), and
on sorted list, the add or insert method ought to add it on the right place.

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: TStringList.Find not working on FPC 3.0.0 (solved)
« Reply #5 on: August 11, 2017, 02:33:13 pm »
Why open three posts/topics for this?

I answered here:
http://forum.lazarus.freepascal.org/index.php/topic,37880.msg255895.html

 

TinyPortal © 2005-2018