Link to home
Start Free TrialLog in
Avatar of lizzzard
lizzzardFlag for Netherlands

asked on

An array of an array of records question...

Hi

I have the following question..
Am I doing this right? The point is I want to make a twodimensional array, which is in fact an array of another array type. This is what I do:

type FoodRec = record
  FoodID : Integer;
  FoodDescr : String[50];
  FoodPortion : String[50];
  FoodKCal : SmallInt;
  FoodFat : SmallInt;
  FoodQuantity : SmallInt;
  FoodRecNo : SmallInt;
end;

type
  MealFoods = Array of FoodRec;

var TotArray : Array of MealFoods;

then I can give it 'room' with setlength(TotArray[4][10]), in which 10 the dimension is of the Mealfoods array (I think..)
Is this the right way to do this?  Or is there a more simple or safer way..

Thanks..

Regards
Avatar of TheNeil
TheNeil

Well it compiles but I'd suggest that you actually define the sizes of your arrays in your type definitions. In your definition the 10 refers to the number of records while the 4 refers to the number of MealFood's. I've never seen SetLength used like that but it compiles and delphi seems happy enough with it but I'd still actually define the dimensions when you crate your types(go on, someone tell me I'm talking rubbish)

The Neil
I have used SetLength with dynamic arrays but typically I've done it as follows:

var TotArray: array of array of FoodRec;
..
..
SetLength(TotArray, I, J);
{gives I x J array)

or...

SetLength(TotArray, I);  Now you have an array of length I (I rows) whose elements you can set to arrays of varying length.  Like  SetLength(TotArray[1],5);

Also, it's pretty nice to use High, Low & Length functions with the dynamic arrays.

Avatar of lizzzard

ASKER

Hi,

Thanks for your comments..

The Neil, I feet the same way as you do, the type definition might get me into trouble. Vendi's solution is I think the one I'm gonna use..

Thanks again,

Lizzzard.
Why don't you use
var
  totarray: array of array of MealFoods;

That is in my oppinion more readable.

Sven
frankly,
  If you find this solution helpful email me at dvaline @ yahoo.com.  And let me at the points. LOL.

  I would create these records as TObject descendants.  Adding as a property to the first level of records a property which is descended off of TList.  This way you can use the power of OO and you can do validation and such as a contained business object.

Example.
  TMyFirstItem = class(TObject)
  private
    fIntItem: Integer;
    fStrItem: String;
    fSecondList: TMySecondList;
  public
    constructor Create;
      //  create the list object
    destructor Destroy; override;
      //  free the list object
    property StringItem: String read fStrItem write fStrItem;
    property IntItem: Integer read fIntItem write fIntItem;
    property SecondList: TMySecondList read fSecondList;
  end;

  TMyFirstList = Class(TList)
  private
    procedure SetItem(Index: Integer; Value: TMyFirstItem);
    function GetItem(Index: Integer): TMyFirstItem;
  public
    function Add: TMyFirstItem;
    procedure Delete(Index: Integer);
      // make sure to free your objects
    procedure Clear;
    property Items[Index: Integer]: TMyFirstItem read GetItem write SetItem;
  end;

  //  you would duplicate this kind of  
  //  declaration for your second item
  //  and list.
Take a look at this

{$R-}

type
  PFoodRec = ^FoodRec;
  FoodRec = record ... end;
type
  MealFoods = array [0..0] of PFoodRec;
 

begin
  MealFoods = new (SizeOf (FoodRec)*WantedItems));

for i:= 1 to WnatedItems-1 do begin
  with MealFoods [i]^ do begin
    ...
  end;
end;

This is not OO, o.k. But it works. You can nest them, if you want. It this is not the thing you want, start building objects as described.
ASKER CERTIFIED SOLUTION
Avatar of Vendi
Vendi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
OK,

Thanks Vendi.. Sorry, I should have asked you myself...

Regards,

Lizzzard