Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.

Thread: Problems with IndexOf This question is answered. Replies: 2 - Last Post: Jan 25, 2015 5:21 PM Last Post By: Bob Richardson
 Posts: 10 Registered: 6/7/00
 Problems with IndexOf Posted: Jan 25, 2015 1:48 PM After filling up a stringlist (SL) I set SL.Sorted := true; This stringlist generally has pairs of entries. Later i := SL.IndexOf(analpha) does not point to the FIRST occurrence. For the last pair of items it points correctly to the first of the pair; for all others it points to the 2nd. For example, if this is the sorted list A1 A1 B1 B1 B2 B2 indexof('A1') = 1 not 0 indexof('B1') = 3 not 2 indexof('B2')= 4, which is correct The same weird results occur when I use Find. If I sort the SL by using SL.Sort (rather than SL.sorted := true), then it all works correctly!!! What's going on? What am I missing? Posts: 467 Registered: 11/3/11
Re: Problems with IndexOf
Posted: Jan 25, 2015 4:20 PM in response to: Bob Richardson
Bob Richardson wrote:
After filling up a stringlist (SL) I set SL.Sorted := true; This stringlist generally has pairs of entries.

Later i := SL.IndexOf(analpha) does not point to the FIRST occurrence. For the last pair of items it points correctly to the first of the pair; for all others it points to the 2nd. For example, if this is the sorted list

A1
A1
B1
B1
B2
B2

indexof('A1') = 1 not 0
indexof('B1') = 3 not 2
indexof('B2')= 4, which is correct

The same weird results occur when I use Find.

If I sort the SL by using SL.Sort (rather than SL.sorted := true), then it all works correctly!!!
What's going on? What am I missing?

``````function TStringList.IndexOf(const S: string): Integer;
begin
if not Sorted then Result := inherited IndexOf(S) else
if not Find(S, Result) then Result := -1;
end;
``````

so when you listed does not have sorted true if uses the inherited IndexOf( s )

``````function TStrings.IndexOf(const S: string): Integer;
begin
for Result := 0 to GetCount - 1 do
if CompareStrings(Get(Result), S) = 0 then Exit;
Result := -1;
end;
``````

Which finds the first match (which is what you want if the sl.sort has been done BUT ifs slow if the list is large)

When you have sorted := true if uses find
``````function TStringList.Find(const S: string; var Index: Integer): Boolean;
var
L, H, I, C: Integer;
begin
Result := False;
L := 0;
H := FCount - 1;
while L <= H do
begin
I := (L + H) shr 1;
C := CompareStrings(FList[I].FString, S);
if C < 0 then L := I + 1 else
begin
H := I - 1;
if C = 0 then
begin
Result := True;
if Duplicates <> dupAccept then L := I;
end;
end;
end;
Index := L;
end;
``````

Which is a binary search that stops when you have found a match in your case which one is effectively random
this is faster on big list

NB .... if Duplicates <> dupAccept then L := I;

--
Linden
"Mango" was Cool but "Wasabi" was Hotter but remember it's all in the "source" Posts: 10 Registered: 6/7/00
 Re: Problems with IndexOf Posted: Jan 25, 2015 5:21 PM in response to: Linden ROTH Which is a binary search that stops when you have found a match in your case which one is effectively random this is faster on big list NB .... if Duplicates <> dupAccept then L := I; So what I needed is to set duplicates to dupAccept....then the IndexOf finds the first occurrence. Thank you Linden All working well now. My list has 23,000 entries and the difference in processing time was substantial. Initially I was using IndexOf on an unsorted list. Sorting and using a binary search on the sorted list really made a huge difference BUT i had to set duplicates. Legend Helpful Answer (5 pts) Correct Answer (10 pts) Server Response from: ETNAJIVE02