Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2022-09

Get highest element of a StringList

17 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

James Richters

I thought I would try:

For Loop := 0 to High(MyStringList) do

But I get "Error: Type mismatch"

Is there a way to get the highest element of a stringlist other than:

For Loop := 0 to MyStringList.Count-1 do

It would be nice to not have the -1
Could High() be made to work if the argument was a stringlist?

James

Reply by email

Bart
to James Richters
PM James Richters wrote
Is there a way to get the highest element of a stringlist other than: For Loop := 0 to MyStringList.Count-1 do

You can use the for .. in loop.

It would be nice to not have the -1 Could High() be made to work if the argument was a stringlist?

Probabaly it could, but it's not likely going to happen.

Bart

Reply by email

Thomas Kurz
to James Richters: I thought I would try: For Loop := 0 to High(MyStringList) do But I get "Error: Type…

Another alternative would be declaring a helper:

type TStringListHelper = class helper for TStringList
function High: NativeInt;
end;
function TStringListHelper.High: NativeInt;
begin
  Exit (Self.Count-1);
end;
Earlier message 21 lines
----- Original Message ----- From: James Richters via fpc-pascal To: 'FPC-Pascal users discussions' Sent: Saturday, September 10, 2022, 18:01:20 Subject: [fpc-pascal] Get highest element of a StringList I thought I would try: For Loop := 0 to High(MyStringList) do But I get "Error: Type mismatch" Is there a way to get the highest element of a stringlist other than: For Loop := 0 to MyStringList.Count-1 do It would be nice to not have the -1 Could High() be made to work if the argument was a stringlist? James

Reply by email

James Richters
to Thomas Kurz

This Helper sounds like a nice way to do it. I need the numerical index of the loop so this would be more straight forward.
Would I then do something like :
For I:= 0 to MyStringList.High Do
?

When I try to add the Type statement:
type TStringListHelper = class helper for TStringList function High: NativeInt; end;
I get Error: Identifier not found "class"

I have the Classes unit. Is there something else I am missing?

James

Another alternative would be declaring a helper: type TStringListHelper = class helper for TStringList function High:
NativeInt; end;
function TStringListHelper.High: NativeInt; begin Exit (Self.Count-1); end;

Reply by email

Thomas Kurz
to James Richters

Try this (note the "modeswitch"):

program Project1;
{$modeswitch typehelpers}

uses
Classes,

  SysUtils;
type TStringListHelper = class helper for TStringList
  function High: NativeInt;
end;
function TStringListHelper.High: NativeInt;
begin
  Exit (Self.Count-1);
end;
var
  f: TStringList = nil;
  i: Integer;
begin
  f := TStringList.Create;
  f.Add ('hallo');
  f.Add ('welt');
  f.Add ('!');
  for i := 0 to f.High do Writeln (f[i]);
  FreeAndNil (f);
end.
Earlier message 30 lines
----- Original Message ----- From: James Richters via fpc-pascal To: 'FPC-Pascal users discussions' Sent: Saturday, September 10, 2022, 19:57:51 Subject: [fpc-pascal] Get highest element of a StringList This Helper sounds like a nice way to do it. I need the numerical index of the loop so this would be more straight forward. Would I then do something like : For I:= 0 to MyStringList.High Do ? When I try to add the Type statement: type TStringListHelper = class helper for TStringList function High: NativeInt; end; I get Error: Identifier not found "class" I have the Classes unit. Is there something else I am missing? James >Another alternative would be declaring a helper: >type TStringListHelper = class helper for TStringList function High: NativeInt; end; >function TStringListHelper.High: NativeInt; begin > Exit (Self.Count-1); >end;

Reply by email

Thomas Kurz
to Thomas Kurz

If you just don't like the "-1" for readability, you might also wan't to consider using

for i := 0 to Pred(f.Count) do ...
Earlier message 72 lines
----- Original Message ----- From: Thomas Kurz via fpc-pascal To: 'FPC-Pascal users discussions' Sent: Saturday, September 10, 2022, 21:37:34 Subject: [fpc-pascal] Get highest element of a StringList Try this (note the "modeswitch"): program Project1; {$modeswitch typehelpers} uses Classes, SysUtils; type TStringListHelper = class helper for TStringList function High: NativeInt; end; function TStringListHelper.High: NativeInt; begin Exit (Self.Count-1); end; var f: TStringList = nil; i: Integer; begin f := TStringList.Create; f.Add ('hallo'); f.Add ('welt'); f.Add ('!'); for i := 0 to f.High do Writeln (f[i]); FreeAndNil (f); end. ----- Original Message ----- From: James Richters via fpc-pascal To: 'FPC-Pascal users discussions' Sent: Saturday, September 10, 2022, 19:57:51 Subject: [fpc-pascal] Get highest element of a StringList This Helper sounds like a nice way to do it. I need the numerical index of the loop so this would be more straight forward. Would I then do something like : For I:= 0 to MyStringList.High Do ? When I try to add the Type statement: type TStringListHelper = class helper for TStringList function High: NativeInt; end; I get Error: Identifier not found "class" I have the Classes unit. Is there something else I am missing? James >Another alternative would be declaring a helper: >type TStringListHelper = class helper for TStringList function High: NativeInt; end; >function TStringListHelper.High: NativeInt; begin > Exit (Self.Count-1); >end;

Reply by email

James Richters
to Thomas Kurz: Try this (note the "modeswitch"): program Project1; {$modeswitch typehelpers} uses…

Thank you for the example! I also needed

{$Mode OBJFPC}

to get it working. I am normally in
{$Mode FPC} Or {$Mode TP}
But I found that if I just put this in a unit that is {$Mode OBJFPC} and include that unit in my {$Mode TP} Unit it works just great!

I have a useless unit that is just a whole list of constants, types, and variables used by my other units, just so I don't have to scroll past over 1000 lines of code just to get to the functions and procedures. It was {$Mode FPC}

For some reason
{$Mode FPC}
{$modeswitch typehelpers}
Still had Error: Identifier not found "class"
So I changed it to
{$Mode OBJFPC}
{$modeswitch typehelpers}
And put the function in it, and it's working great!

My main reason for wanting something like this is because I occasionally will forget the -1 and... well... that's no good... Since I recently learned of High() and Low() for arrays, I've been changing all my for loops with arrays to use High() and sometimes Low() if they don't 's also helpful to do something like:

MyArray[High(MyArray)] := something;

To write to a newly added array element where I used to have

MyArray[Length(MyArray)-1] := something;

While it does work.. it's less readable and prone to errors.

James

Reply by email

Travis Siegel
to Thomas Kurz: If you just don't like the "-1" for readability, you might also wan't to consider using…

But, if that (eventually) leads to the highest one, and that's all that's desired, why not just use the whole expression variable := pred(f.Count) instead of the whole loop?

Wouldn't that accomplish the same thing?

Why the loop?

Thomas Kurz wrote 86 lines
If you just don't like the "-1" for readability, you might also wan't to consider using for i := 0 to Pred(f.Count) do ... ----- Original Message ----- From: Thomas Kurz via fpc-pascal To: 'FPC-Pascal users discussions' Sent: Saturday, September 10, 2022, 21:37:34 Subject: [fpc-pascal] Get highest element of a StringList Try this (note the "modeswitch"): program Project1; {$modeswitch typehelpers} uses Classes, SysUtils; type TStringListHelper = class helper for TStringList function High: NativeInt; end; function TStringListHelper.High: NativeInt; begin Exit (Self.Count-1); end; var f: TStringList = nil; i: Integer; begin f := TStringList.Create; f.Add ('hallo'); f.Add ('welt'); f.Add ('!'); for i := 0 to f.High do Writeln (f[i]); FreeAndNil (f); end. ----- Original Message ----- From: James Richters via fpc-pascal To: 'FPC-Pascal users discussions' Sent: Saturday, September 10, 2022, 19:57:51 Subject: [fpc-pascal] Get highest element of a StringList This Helper sounds like a nice way to do it. I need the numerical index of the loop so this would be more straight forward. Would I then do something like : For I:= 0 to MyStringList.High Do ? When I try to add the Type statement: type TStringListHelper = class helper for TStringList function High: NativeInt; end; I get Error: Identifier not found "class" I have the Classes unit. Is there something else I am missing? James > Another alternative would be declaring a helper: > type TStringListHelper = class helper for TStringList function High: NativeInt; end; > function TStringListHelper.High: NativeInt; begin > Exit (Self.Count-1); > end; _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Sven Barth
to James Richters: Thank you for the example! I also needed {$Mode OBJFPC} to get it working. I am normally…

James Richters via fpc-pascal schrieb am
Sa., 10. Sep. 2022, 22:55:

Show quoted text 6 lines
For some reason {$Mode FPC} {$modeswitch typehelpers} Still had Error: Identifier not found "class"

Because support for the "class" keyword is only available when the modeswitch Class is enabled which is the case for the ObjFPC and Delphi modes.
You don't need the TypeHelpers mode switch for "class helper", only for "type helper".

Regards,
Sven

Reply by email

James Richters
to Travis Siegel: But, if that (eventually) leads to the highest one, and that's all that's desired, why…

The loops is just an example because in my original post of why I wanted to get the highest element of a stringlist was because I wanted a for loop that wasn't as clumsy as

For I:=0 to myStringlist.count-1 Do

This came up because thanks to this discussion list, I learned I could use High() and Low() for my dynamic arrays, so I went through replacing all instances of

Length(MyDynamicArray)-1 with High(MyDynamicArray)

So my for loops went from:

For I:=0 to Length(MyDynamicArray)-1 Do
To
For I:=0 to High(MyDynamicArray) Do

Which I find much more clear and less prone to problems.. I have forgot the -1 before and it gives range check errors of course.. so I'm switching everything to use High() instead and will just automatically use High() in the future, thus preventing the issue all together.

I'm really happy with the helper function and using MyStringList.High. I think .High should just be added to all things that have a .Count because everyone always needs it ALL THE TIME. But I am happy it's possible to add a helper function to add it myself.

James

Why the loop?

Reply by email

Jean SUZINEAU
to James Richters
As Bart suggested, you can use too the for/in loop:  for s in sl do
WriteLn( s);

For example:

var
    sl: TStringList;
    s: String;
begin
      sl:= TStringList.Create;
      try
         sl.Add('1');
         sl.Add('2');
         for s in sl do WriteLn( s);
      finally
             FreeAndNil( sl);
             end;
end.

Output:

1
2

This works on arrays and strings too.

Reply by email

James Richters
to Jean SUZINEAU: As Bart suggested, you can use too the for/in loop:  for s in sl do WriteLn( s); For…

The problem with the for in loop is that I need the index.

I'm sometimes searching through the stringlist looking for a match, and when I find a match, I want to read the value And then do a break, because there is no point is searching once I found what I am looking for:

For I:= 0 to MyStringlist.high Do
   Begin
       If MyStringlist[I].Names = SearchName Then
          Begin
                MyValue := MyStringlist[I].ValueFromIndex;
                Break;
          End;
   End;

I agree that the for - in loop is a great way if you are always processing the entire list and don't need the index for anything.

James

Reply by email

James Richters
to Martin Wynne

So.... I could just do this?

Index:= MyStringlist.IndexOfName(SearchName);
If Index >=0 then
   MyValue := MyStringlist[Index].ValueFromIndex;

That sure is nice to know, Thank you!

I guess for my dynamic arrays of records, I still need to search with a loop... or is there a cool thing I don't know about for that as well?

James

Reply by email

Martin Wynne
to James Richters
James Richters wrote 6 lines
So.... I could just do this? Index:= MyStringlist.IndexOfName(SearchName); If Index >=0 then MyValue := MyStringlist[Index].ValueFromIndex;

Hi James,

I would probably do

try
   with MyStringList do MyValue:=ValueFromIndex[IndexOfName(SearchName)];
except
   MyValue:='';
end;

cheers,

Martin.

Reply by email