2

I would like to create a program (learning Delphi) that takes 3 different list (from TEdit)

  1. A list of names
  2. A list of names to ignore when searching first list
  3. A list of names to ignore when searching first list

By taking the 3 TEdit and converting the text to TStringList and seperating (I am so far okay with this).

I want to output the first name (or item) of the first list that is neither on 2nd or 3rd list

procedure TForm1.Button1Click(Sender: TObject);
var
i, j ,k : integer;
begin


  list := TStringList.Create;
  ignoreListFirst := TStringList.Create;
  ignoreListSecond := TStringList.Create;

  list.Delimiter := ',';
  ignoreListFirst.Delimiter := ',';
  ignoreListSecond.Delimiter := ',';

  list.DelimitedText := EditList.Text;
  ignoreListFirst.DelimitedText := EditIgnoreList1.Text;
  ignoreListSecond.DelimitedText := EditIgnoreList2.Text;

  for k := 0 to list.Count - 1 do
  begin
    for i := 0 to ignoreListFirst.Count - 1 do
    begin
      for j := 0 to ignoreListSecond.Count - 1 do
      begin
        if (list[k] <> ignoreListFirst[i]) and (list[k] <> ignoreListSecond[k]) then

        EditResult.Text := list[k];
        break;

      end;
    end;
  end;

  list.Free;
  ignoreListFirst.Free;
  ignoreListSecond.Free;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  EditList.Text := 'Katy,Mary,John,Maggie,Carl';
  EditIgnoreList1.Text := 'Katy,Mary,John';
  EditIgnoreList2.Text := 'John,Carl';
end;

Tried swapping the loop order to see if I can pinpoint the problem.

first list in last loop give me no errors and produces the name 'Katy' which is yes, the first on the list but ignored.

Swapped the the first list to be first loop. produces 'Mary' which I guess ignored (which I wanted) Katy but not others from what I can see.

In this example (which does not work) I want it to result 'Maggie' which is not on either ignore lists.

Thanks and sorry if I explained this wrong. Learning Delphi. Do pinpoint any mistakes.

8
  • 1
    Follow this through in the debugger. Look what happens in the inner most loop. Watch how j never exceeds 0. Commented May 29, 2019 at 15:06
  • As David said you are missing a Begin....End; block use the debugger to follow the error. The if statement is not doing what you think it does. Commented May 29, 2019 at 15:30
  • In addition to what others have said, it may also be useful to give meaningful names to indexes (instead of i, j, k), especially when you have many in play simultaneously. Commented May 29, 2019 at 15:43
  • 1
    Please don't add an answer to the question. Answers are to be provided as answers. Take the tour. As far as debugging goes, you are making life hard for yourself by not learning the basics of debugging. Don't waste any more time. Commented May 29, 2019 at 16:43
  • 2
    debugger is something I am not comfortable with Then this is an excellent opportunity for you to become more comfortable with it, isn't it? It's a relatively easy thing to debug, and avoiding the debugger will never let you become more used to it. The debugger is one of the best tools in a developer's toolbox, and the sooner you become comfortable with it the sooner you'll be able to figure out problems yourself. Commented May 29, 2019 at 17:00

3 Answers 3

1

While messing around with debugger and following the suggestions given I came to the answer bellow.

procedure TForm1.Button1Click(Sender: TObject);
var
  iList, iListFirst ,iListSecond : integer;
  found : boolean;
begin

  list := TStringList.Create;
  ignoreListFirst := TStringList.Create;
  ignoreListSecond := TStringList.Create;

  list.Delimiter := ',';
  ignoreListFirst.Delimiter := ',';
  ignoreListSecond.Delimiter := ',';

  list.DelimitedText := EditList.Text;
  ignoreListFirst.DelimitedText := EditIgnoreList1.Text;
  ignoreListSecond.DelimitedText := EditIgnoreList2.Text;

  for iList := 0 to list.Count - 1 do
  begin
    for iListFirst := 0 to ignoreListFirst.Count - 1 do
    begin
      found := false;
      if list[iList] = ignoreListFirst[iListFirst] then
      begin
        found := true;
        break
      end;
    end;
    if not found then
    begin
      for iListSecond := 0 to ignoreListSecond.Count - 1 do
      begin
        if list[iList] = ignoreListSecond[iListSecond] then
        begin
          found := true;
          break
        end;
      end;
    end;
    if not found then
    begin
      EditResult.Text := list[iList];
      break
    end;
  end;

  list.Free;
  ignoreListFirst.Free;
  ignoreListSecond.Free;

end;
Sign up to request clarification or add additional context in comments.

Comments

0

Basicaly your missing a begin/end.

for k := 0 to list.Count - 1 do
begin
 for i := 0 to ignoreListFirst.Count - 1 do
 begin
  for j := 0 to ignoreListSecond.Count - 1 do
  begin
    if (list[k] <> ignoreListFirst[i]) and (list[k] <> ignoreListSecond[k]) then
    Begin // here

      EditResult.Text := list[k];
      break;
    End; // here
  end;
 end;
end;

In the old code, your loop will alway break. When not using begin/end only the first line of code following the if, will be dependant of the if condition. The second line will always execute.

Seconde: break, will only break on the most inner loop. So the two other loop will just continue and therefor another name might be shown...

But instead of using two extra inner loops, you could check if the currect string of the first loop exists inside one of the other loops (see TstringList.IndexOf)

Comments

0

I'll do as follows, using TStrings.IndexOf function.

Note: Remember to free your lists in a try-finally block or you will generate memory leaks, sooner or later.

var
  List : TStrings;
  IgnoreListFirst : TStrings;
  IgnoreListSecond : TStrings;
  i : integer;
begin
  List := TStringList.Create;
  IgnoreListFirst := TStringList.Create;
  IgnoreListSecond := TStringList.Create;
  try
    List.Delimiter := ',';
    IgnoreListFirst.Delimiter := ',';
    IgnoreListSecond.Delimiter := ',';

    List.DelimitedText := EditList.Text;
    IgnoreListFirst.DelimitedText := EditIgnoreList1.Text;
    IgnoreListSecond.DelimitedText := EditIgnoreList2.Text;

    for i := 0 to List.Count do
    begin
      if(IgnoreListFirst.IndexOf(List[i]) = -1) and (IgnoreListSecond.IndexOf(List[i]) = -1) then
      begin
        EditResult.Text := List[i];
        Exit;
      end;
    end;

  finally
    IgnoreListSecond.Free;
    IgnoreListFirst.Free;
    List.Free;
  end;
end;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.