0

In Delphi 10 Seattle, I am trying to parse a JSON that contains an array of strings in a property.

As an example, consider this:

{
  "name":"Joe",
  "age":45,
  "languages":["c++", "java", "cobol"]
} 

How do I parse languages to obtain an array of strings?

1
  • with TJSONObject Commented Jan 4, 2022 at 9:37

3 Answers 3

3

Try something like this:

function GetLanguagesArray(const AJSON: String): TArray<String>;
var
  LValue: TJSONValue;
  LArray: TJSONArray;
  i: Integer;
begin
  Result := nil;
  LValue := TJSONObject.ParseJSONValue(AJSON);
  if LValue <> nil then
  try
    LArray := (LValue as TJSONObject).GetValue('languages') as TJSONArray;
    SetLength(Result, LArray.Count);
    for i := 0 to Pred(LArray.Count) do
    begin
      Result[i] := LArray[i].Value;
    end;
  finally
    LValue.Free;
  end;
end;
Sign up to request clarification or add additional context in comments.

Comments

1

Very easy with REST.JSON, using helper to parse and read array items

type
  TDeveloper = class
  private
    FAge      : Integer;
    FName     : string;
    FLanguages: TArray<string>;
  public
    property Age      : Integer        read FAge       write FAge;
    property Name     : string         read FName      write FName;
    property Languages: TArray<string> read FLanguages write FLanguages;
  end;

// Sample
var
  FDeveloper: TDeveloper;
  FLanguage : string;
begin
  try
    FDeveloper := TJson.JsonToObject<TDeveloper>(Memo1.Text);
    Memo2.Clear;
    Memo2.Lines.Add('------------------------------ ');
    Memo2.Lines.Add('Name: ' + FDeveloper.Name);
    Memo2.Lines.Add('Age : ' + FDeveloper.Age.ToString);

    for FLanguage in FDeveloper.Languages do
    begin
      Memo2.Lines.Add('------------------------------ ');
      Memo2.Lines.Add(FLanguage);
    end;
  finally
    FreeAndNil(FDeveloper);
  end;

See image: [1]: https://i.sstatic.net/69Zao.png

Comments

0
function TForm1.GetLangArray(const AJSONStr: String): TArray<String>;
var
  AJSONVal, AJSONElem: TJSONValue;
  AJSONArray: TJSONArray;
  i: Integer;
begin
  AJSONVal := TJSONObject.ParseJSONValue(AJSONStr);
  AJSONVal := AJSONVal.P['languages'];

  if (AJSONVal is TJSONArray) then
    AJSONArray := AJSONVal as TJSONArray
  else
    Exit;

  with AJSONArray do
  begin
    SetLength(Result, Count);
    i := 0;
    for AJSONElem in AJSONArray  do
    begin
      Result[i] := AJSONelem.Value;
      Inc(i);
    end;
  end;
end;

UPDATE

thanks to @RemyLebeau for the comment. I fixed the memory leak of previous code:

function TForm1.GetLangArray(const AJSONStr: String): TArray<String>;
var
  AJSONVal, AJSONElem: TJSONValue;
  AJSONArray: TJSONArray;
  i: Integer;
begin
  AJSONVal := TJSONObject.ParseJSONValue(AJSONStr);
  try
    AJSONArray := AJSONVal.P['languages'] as TJSONArray;

    with AJSONArray do
    begin
      SetLength(Result, Count);
      i := 0;
      for AJSONElem in AJSONArray  do
      begin
        Result[i] := AJSONElem.Value;
        Inc(i);
      end;
    end;
  finally
    AJSONVal.Free;
  end;
end;

7 Comments

I get compiler error on "AJSONVal.P['languages'];"
@Girish No. the code is clean. What's your compiler error?
I get --[dcc32 Error] Unit3.pas(168): E2003 Undeclared identifier: 'P'
@Girish are you sure that System.JSON is used?
The TJSONValue.P[] property does not exist in 10.0 Seattle, it was added in 10.3 Rio. You will have to type-cast the parsed TJSONValue to TJSONObject and then use its Values[] property or GetValue() method to access the languages array. Also, this code is leaking the parsed TJSONValue returned from TJSONObject.ParseJSONValue(), you need to Free() it when you are done using it. Which means using a separate variable to retrieve the languages TJSONValue into.
|

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.