Instead of using IndexOf
, sort both lists before, to prevent searching the whole list at every cycle. Furthermore, it is possible to achieve this in one single loop.
Assuming you want the results in two separate string lists, try the following:
procedure CompareStringLists(List1, List2: TStringList;
Missing1, Missing2: TStrings);
var
I: Integer;
J: Integer;
begin
List1.Sort;
List2.Sort;
I := 0;
J := 0;
while (I < List1.Count) and (J < List2.Count) do
begin
if List1[I] < List2[J] then
begin
Missing2.Add(List1[I]);
Inc(I);
end
else if List1[I] > List2[J] then
begin
Missing1.Add(List2[J]);
Inc(J);
end
else
begin
Inc(I);
Inc(J);
end;
end;
for I := I to List1.Count - 1 do
Missing2.Add(List1[I]);
for J := J to List2.Count - 1 do
Missing1.Add(List2[J]);
end;
Usage:
procedure TForm1.Button1Click(Sender: TObject);
var
List1: TStringList;
List2: TStringList;
begin
List1 := TStringList.Create;
List2 := TStringList.Create;
try
List1.CommaText := 'A, C, F, G, H, K, L, M, N, O, Q, R';
List2.CommaText := 'C, D, E, F, J, P, Q, S, T, U, V, W';
Memo1.Lines.Assign(List1);
Memo2.Lines.Assign(List2);
CompareStringLists(List1, List2, Memo3.Lines, Memo4.Lines);
finally
List2.Free;
List1.Free;
end;
end;