1

I have a memo many 'mango' lines in it and I want to count how many times it finds the text 'mango'.

var
  f, mango: Integer;
begin
  mango := 0;
  for f := 0 to m0.lines.Count - 1 do
  begin
    if AnsiContainsStr(m0.lines[f], 'mango') then
    begin
      mango := mango + 1;
      m0.lines.Add(IntToStr(mango));
    end
  end;
end;

But the result, for example, if it found six 'mango' entries would be like this:

1
2
3
4
5
6

How can i have result only 6?

Michael
  • 41,989
  • 11
  • 82
  • 128
Bianca
  • 973
  • 2
  • 14
  • 33

1 Answers1

8

If you only want the total displayed in the memo then you will need to do this:

var
  f, mango: Integer;
begin
  mango := 0;
  for f := 0 to m0.lines.Count - 1 do
  begin
    if AnsiContainsStr(m0.lines[f], 'mango') then
    begin
      mango := mango + 1;
    end
  end;
  m0.lines.Add(IntToStr(mango));    // This line needs to be outside of your loop
end;

You were adding the count to the list each time it was incremented.

If you wanted a reusable function for this you can use something like this:

function CountStringListTexts(const ASearchList: TStrings; const ASearchText: string): Integer;
var
  f: Integer;
begin
  Result := 0;
  for f := 0 to ASearchList.Count - 1 do
  begin
    if AnsiContainsStr(ASearchList[f], ASearchText) then
    begin
      Result := Result + 1;
    end
  end;
end;

To use this you can then do:

m0.lines.Add(IntToStr(CountStringListTexts(m0.Lines, 'mango')));

This can also be made into a class helper:

type
  TSClassHelper = class helper for TStrings
    function CountMatchTexts(const ASearchText: string): Integer;
  end;

function TSClassHelper.CountMatchTexts(const ASearchText: string): Integer;
var
  f: Integer;
begin
  Result := 0;
  for f := 0 to Self.Count - 1 do
  begin
    if AnsiContainsStr(Self.Strings[f], ASearchText) then
    begin
      Result := Result + 1;
    end
  end;
end;

Using this would be very easy. You would just do:

m0.lines.Add(IntToStr(m0.Lines.CountMatchTexts('mango')));
Graymatter
  • 6,529
  • 2
  • 30
  • 50
  • AHA! that simple? Thanks you @graymatter. – Bianca May 04 '14 at 06:12
  • +1 question: How to make code that have function like this? Further more, I will use the function on different string. So i don't need to type the same things over and over again. – Bianca May 04 '14 at 06:16
  • 1
    @Bianca Added a more generic function for you. – Graymatter May 04 '14 at 06:20
  • 2
    If you change the procedure to accept `TStrings` instance you really have a generic function without the VCL dependency – Sir Rufo May 04 '14 at 12:03
  • @SirRufo I can't believe I didn't think of that. I have updated the answer accordingly. I also added a class helper. – Graymatter May 04 '14 at 17:28
  • Now a +1 - Sometimes you get in touch with the Tree-Forest-Syndrome (too many trees to see the forest) :o) – Sir Rufo May 04 '14 at 17:49
  • @SirRufo I had "I couldn't see the forest for the trees" in my first comment responding to you but then I saw a bug in the code and quickly fixed it. When I got back to the comment telling you about the change I forgot to put it back in :) – Graymatter May 04 '14 at 17:51