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?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
UnDiUdin
  • 14,924
  • 39
  • 151
  • 249

3 Answers3

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;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
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.stack.imgur.com/69Zao.png

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;
Amin Alinezhad
  • 132
  • 1
  • 8
  • I get compiler error on "AJSONVal.P['languages'];" – Girish Jan 04 '22 at 12:20
  • @Girish No. the code is clean. What's your compiler error? – Amin Alinezhad Jan 04 '22 at 12:34
  • I get --[dcc32 Error] Unit3.pas(168): E2003 Undeclared identifier: 'P' – Girish Jan 04 '22 at 12:56
  • @Girish are you sure that `System.JSON` is used? – Amin Alinezhad Jan 04 '22 at 13:21
  • Yes, otherwise it will give error on very first line. – Girish Jan 04 '22 at 14:36
  • 2
    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. – Remy Lebeau Jan 04 '22 at 21:11
  • thanks to @RemyLebeau. I fixed the memory leak. – Amin Alinezhad Jan 05 '22 at 08:37