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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mokuleCommented:
Yes You should loop this way
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
wildzeroAuthor Commented:
What about getting a count of the number of items in the set?
0
developmentguruPresidentCommented:
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
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

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
kretzschmarCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.