kathrine jensen
kathrine jensen

Reputation: 145

Variable in for loop is not getting called

I am using DBXJson to parse a simple json file called response.jsonand show it's contents in a grid, but only the first row of the grid ever gets populated with the data and even though there is more rows/data to display. I am using a custom grid in the code below but I have tried a variation of the below code using the standard stringgrid and it exhibited the same behavior. This is the code I am using to parse the response and show it in my grid.

var
  sl: TStringList;
  LJsonArr: TJSONArray;
  LJsonValue: TJSONValue;
  LItem: TJSONValue;
  col, row: Integer;
begin
  col := 0;
  row := 0;

  sl := TStringList.Create;
  sl.LoadFromFile('response.txt');
  LJsonArr := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(sl.text), 0)
    as TJSONArray;

  for LJsonValue in LJsonArr do
  begin
    NextGrid1.AddRow();

    for LItem in TJSONArray(LJsonValue) do
    begin
      NextGrid1.Cells[col, row] := TJSONPair(LItem).JsonValue.Value;
      inc(col);
    end;
    inc(row);
  end;
  sl.Free;
end;

I suspect that the problem lies in the fact that the row variable is out of place and is not getting called and that is causing only the first row to display, but I could be mistaken and I am hoping that a fresh pair of eyes can spot the problem.

Upvotes: 3

Views: 120

Answers (1)

David Heffernan
David Heffernan

Reputation: 612954

The problem is that col must be re-initialised to zero every time you start a new row. So move the initialization of col into the outer loop.

row := 0;
for LJsonValue in LJsonArr do
begin
  col := 0;
  NextGrid1.AddRow();
  for LItem in TJSONArray(LJsonValue) do
  begin
    NextGrid1.Cells[col,row] := TJSONPair(LItem).JsonValue.Value;
    inc(col);
  end;
  inc(row);
end;

I don't know this JSON library but if it allows you to access array elements with random access then a traditional oindexed for loop would lead to cleaner code that the for in loop that you use. In pseudo code:

for row := 0 to arr.length do
begin
  item := arr[row];
  for col := 0 to item.length do
    grid.Cells[col,row] := item[col];
end;

As a rule of thumb, for in loops are better if you do not need to know the item index. However, as soon as you need to know the item index then traditional indexed for loops are usually to be preferred.

Upvotes: 4

Related Questions