6

I'm trying to create an array to store every item of a TStringList into an array which size may vary depending on the quantity of items in said TStringList.

I know my syntax is wrong and what I want is probably a dynamic array, so the [0..100] is probably wrong aswell but I could not find any alternative syntax online.

ProductAvailabilityResult = Class(TRemotable)
private
  FResultArray : array[1..100] of string;
published
  property ResultArray[Index: Integer]: array of string read FResultArray write FResultArray;
End;

And this is how I would invoke it and populate it. conditionList being my TStringList which I would populate into my array.

for I := 0 to conditionList.Count - 1 do
begin
  aProductAvailabilityResult.ResultArray[I] := conditionList[I];
end;

In case you may or may not have alternative suggestions to what i'm doing, the reason for this setup is because it's a web service app sending results over a SOAP server, and I don't think my PHP/Soap client can read TStringLists, so I need to pass it to an array first.

Let me know, Thanks!

5
  • The entire question hinges on the remoting, and how that is to be achieved. Why is your code so poorly indented? Commented Nov 23, 2016 at 17:09
  • @DavidHeffernan I'm confused, the question does not hinge on remoting by any means. I want to know how I can declare a generic dynamic array which my for loop will populate with the contexts of a TStringList. I can handle the array just fine remotely. Also the indenting issue comes from copy & pasting. It screws up the alignments, so I have to manually space to get the code block on stackoverflow. Commented Nov 23, 2016 at 17:10
  • If you want a dynamic array, declare a dynamic array. But you don't have a dynamic array at the moment. You have an array property. Different altogether. You said "I don't think my PHP/Soap client can read TStringLists". So presumably it matters what it can read. Supposed I show you how to create a dynamic array property. Will you promise not to complain if your PHP/Soap client cannot read it? Commented Nov 23, 2016 at 17:13
  • Use CTRL+K to format blocks here. The edit window has extensive help. Avail yourself of it. Well presented questions are more attractive to us. Commented Nov 23, 2016 at 17:14
  • I want a dynamic array property, how do I acheive that? Commented Nov 23, 2016 at 17:14

2 Answers 2

6

Your syntax for declaring an array property is close, but you need to use getter/setter methods instead of direct field access, and array properties cannot be declared as published:

type
  ProductAvailabilityResult = class(TRemotable)
  private
    FResultArray : array of string;
    function GetResultArray(Index: Integer): string;
    function GetResultArrayCount: Integer;
    procedure SetResultArray(Index: Integer; const Value: string);
    procedure SetResultArrayCount(Value: Integer);
  public
    property ResultArray[Index: Integer]: string read GetResultArray write SetResultArray default;
    property ResultArrayCount: Integer read GetResultArrayCount write SetResultArrayCount;
  end;

function ProductAvailabilityResult.GetResultArray(Index: Integer): string;
begin
  Result := FResultArray[Index];
end;

function ProductAvailabilityResult.GetResultArrayCount: Integer;
begin
  Result := Length(FResultArray);
end;

procedure ProductAvailabilityResult.SetResultArray(Index: Integer; const Value: string);
begin
  FResultArray[Index] := Value;
end;

procedure ProductAvailabilityResult.SetResultArrayCount(Value: Integer);
begin
  SetLength(FResultArray, Value);
end;

Then you can do this:

aProductAvailabilityResult.ResultArrayCount := conditionList.Count;
for I := 0 to conditionList.Count - 1 do
begin
  aProductAvailabilityResult[I] := conditionList[I];
end;

You might want to consider adding a method to copy strings from a source TStrings:

type
  ProductAvailabilityResult = class(TRemotable)
  private
    ...
  public
    procedure AssignStrings(AStrings: TStrings);
    ...
  end;

procedure ProductAvailabilityResult.AssignStrings(AStrings: TStrings);
var
  I: Integer;
begin
  SetLength(FResultArray, AStrings.Count);
  for I := 0 to AStrings.Count - 1 do
    FResultArray[I] := AStrings[I];
end;

aProductAvailabilityResult.AssignStrings(conditionList);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks this was also very helpful.
3

You've declared an array property, albeit with some syntax errors. However, you state in the question and comments that you want a property that is a dynamic array. That's different from an array property.

Declare a dynamic array property like so:

type
  ProductAvailabilityResult = class(TRemotable)
  private
    FResultArray: TArray<string>;
  published
    property ResultArray: TArray<string> read FResultArray write FResultArray;
  end;

Populate it like this:

var
  i: Integer;
  List: TStringList;
  par: ProductAvailabilityResult;
  arr: TArray<string>;
....
List := ...;
par := ...;
SetLength(arr, List.Count);
for i := 0 to List.Count-1 do
  arr[i] := List[i];
par.ResultArray := arr;

1 Comment

Thanks this did the trick, sorry for not exactly knowing the in and out of etiquette. I realize this site more than your typical forum has stricter guidelines and a method of workflow that people asking/answering questions are used to. I'm not a power user of SO yet so you'll excuse my poorly formulated question. Thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.