Jump to content
robertjohns

Deleting string wich does include number

Recommended Posts

I am using Delphi 10

 

Is there any way to delete a string which does not contain number with it

 

like

 

abc

def23

fgr65

kbt

idopt87

 

How can I delete the bold one because it does contain number with it

 

Thanks in advance

 

Share this post


Link to post

There is no magic function for this.
F.x. you could for each string, go through each character and increment a counter if the character is a number. If the counter = 0 after the count, the word should be excluded?

Edit: There also is an optimization that can be applied to the above suggestion.

 

Share this post


Link to post

I would use Break on the first find, and set some variable to True

Share this post


Link to post

The simplest solution that came to my mind.

procedure Tf_TesterMain.DeleteStringsWithoutDigits;
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    List.Add('abc');
    List.Add('def23');
    List.Add('fgr65');
    List.Add('kbt');
    List.Add('idopt87');
    doWithList(List);
  finally
    FreeAndNil(List);
  end;
end;

...

procedure doWithList(_List: TStringList);
var
  i: Integer;
begin
  for i := _List.Count - 1 downto 0 do begin
    if not ContainsDigit(_List[i]) then begin
      _List.Delete(i);
    end;
  end;
end;

...

function ContainsDigit(const _Text: string): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := 1 to Length(_Text) do begin
    if _Text[i] in ['0'..'9'] then begin
      Result := True;
      Break;
    end;
  end;
end;

 

  • Like 1

Share this post


Link to post
37 minutes ago, PaPaNi said:

The simplest solution that came to my mind.


procedure Tf_TesterMain.DeleteStringsWithoutDigits;
var
  List: TStringList;
begin
  List := TStringList.Create;
  try
    List.Add('abc');
    List.Add('def23');
    List.Add('fgr65');
    List.Add('kbt');
    List.Add('idopt87');
    doWithList(List);
  finally
    FreeAndNil(List);
  end;
end;

...

procedure doWithList(_List: TStringList);
var
  i: Integer;
begin
  for i := _List.Count - 1 downto 0 do begin
    if not ContainsDigit(_List[i]) then begin
      _List.Delete(i);
    end;
  end;
end;

...

function ContainsDigit(const _Text: string): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := 1 to Length(_Text) do begin
    if _Text[i] in ['0'..'9'] then begin
      Result := True;
      Break;
    end;
  end;
end;

 

Thanks PaPaNi Really appreciable solution and help my problem solved, thanks again

Share this post


Link to post

It would be also an option to use IndexOfAny, like this:

 

unit UMain_Frm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Memo.Types, FMX.Layouts,
  FMX.ScrollBox, FMX.Memo;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Layout1: TLayout;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

const
    CDigitChars  : array [ 0..9 ] of Char = ('0','1','2','3','4','5','6','7','8','9' );

procedure doWithList( AList : TStrings );
var
    i: Integer;
begin

    AList.BeginUpdate;

    try

        for i := AList.Count - 1 downto 0 do
        begin

            if AList[ i ].IndexOfAny( CDigitChars ) < 0 then
            begin
                AList.Delete( i );
            end;

        end;

    finally
        AList.EndUpdate;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin

    var LList := TStringList.Create;
    try
        LList.Assign( Memo1.Lines );

//        LList.Add( 'abc'     );
//        LList.Add( 'def23'   );
//        LList.Add( 'fgr65'   );
//        LList.Add( 'kbt'     );
//        LList.Add( 'idopt87' );

        doWithList( LList );

        Memo1.Lines.Assign( LList );

    finally
        FreeAndNil( LList );
    end;

end;

end.

 

Share this post


Link to post

I would probably use LastDelimiter(), especially since the example in question shows digits are at the end of the strings, eg:

function ContainsDigit(const _Text: string): Boolean;
begin
  Result := LastDelimiter('0123456789', _Text) > 0;
end;

Or:

function ContainsDigit(const _Text: string): Boolean;
begin
  Result := _Text.LastDelimiter('0123456789') > -1;
  //or:
  //Result := _Text.LastDelimiter(['0'..'9']) > -1;
end;

 

  • Like 1

Share this post


Link to post

Right, could be also written like that:

            //if AList[ i ].IndexOfAny( CDigitChars ) < 0 then
            if AList[ i ].LastIndexOfAny( CDigitChars ) < 0 then
            begin
                AList.Delete( i );
            end;

 

Share this post


Link to post

I prefer not to give explicit answers to educational questions.

Having to understand a description of how to implement the answer is better learning than being given the answer.

That said: LastDelimiter - a little tidbit that I didn't know existed - although it appears to origin from the days of PChar.

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×