Enumerated types and sets of - counts and loops

:-)
Lets say I have this.

type
  TThing = (tgsOne, tgsTwo, tgsThree);
  TThings = set of TThing;

and then I do

var
  Things : TThings;
begin
  include(Things,tgsOne);

and that is all good, Things now contains tgsOne in the set.
then I do this
include(Things,tgsTwo);

now I want to know how many items are in the set.
showmessage( IntToStr(length(Things)) );
that dosn't want to work.

Also how can I loop the items in my set to see if they are in there/do stuff. Do I have to do
var
  Things : TThings;
  Thing : TThing;
begin
  include(Things,tgsOne);

  For Thing := low(TThing) to high(Thing) do
    If Thing in Things then
     //-- do something

:-)



LVL 10
wildzeroAsked:
Who is Participating?
 
mokuleConnect With a Mentor Commented:
Yes You should loop this way
0
 
wildzeroAuthor Commented:
What about getting a count of the number of items in the set?
0
 
developmentguruConnect With a Mentor PresidentCommented:
Where you have
  //-- Do Something
put in
  Inc(Count);

There are faster ways of doing this.  The problem is that Delphi places sets in an appropriately sized container.  Your set would fit in one byte.  Bigger sets would use 2 or 4 bytes depending on what they need.  If you want a general function to count the number of elements in a set I would do something like the following pseudocode.  Passing an integer will type cast the set to an integer value which will allow it to handle all currently allowable set sizes.  If you need more speed than that you can use the same logic in assemly language.  Let me know if there are questions.
function CountSetItems(SetValue : integer) : byte;
var
  Mask, Count : integer;
 
begin
  Mask := $80000000;
  Count := 0;
  While Mask <> 0 do
    begin
      if SetValue and Mask <> 0 then
        inc(Count);
      Mask := Mask shr 1;
    end;
  Result := Count;
end;

Open in new window

0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
developmentguruPresidentCommented:
P.S.  the pseudo code I posted has the added advantage that it does not matter what type of set you pass it.  The down side is that it tests for values that cannot exist within a specific set (it is testing for all 32 possibilities - if your set only contains 3...).  It should be possible to create a function where you pass in the type of set and the value and it counts it by looping the appropriate number of times for the set.  I just don't have time to try it tonight, sorry.
0
 
ziolkoCommented:
just wondering what if you do this:
Include(Things, tgsNothing);
will Things contain any elements or will it contain nothing? ;)


sorry couldn't resist:)

ziolko.
0
 
kretzschmarConnect With a Mentor Commented:
a small sample

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TThing = (tgsOne, tgsTwo, tgsThree);
  TThings = set of TThing;


function getSetCount(aSet : TThings) : integer;
var
  i : TThing;
begin
  result := 0;
  for i := low(TThing) to high(TThing) do
  begin
    if (i in aset) then
      inc(result);
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  ThingSet : TThings;
begin
  ThingSet := [tgsOne, tgsTwo];
  showmessage('Items in Set: '+inttostr(getSetCount(ThingSet)));
  ThingSet := ThingSet - [tgsOne];
  showmessage('Items in Set: '+inttostr(getSetCount(ThingSet)));
  ThingSet := ThingSet + [tgsThree];
  showmessage('Items in Set: '+inttostr(getSetCount(ThingSet)));
  ThingSet := ThingSet + [tgsOne];
  showmessage('Items in Set: '+inttostr(getSetCount(ThingSet)));
  ThingSet := [];
  showmessage('Items in Set: '+inttostr(getSetCount(ThingSet)));
end;

end.

meikl ;-)
0
 
Computer101Commented:
Forced accept.

Computer101
EE Admin
0
All Courses

From novice to tech pro — start learning today.