#1 2022-05-02 11:16:23

tbo
Member
Registered: 2015-04-20
Posts: 335

Problem with ReduceAsArray()

Delphi 11.1, mORMot 3294

Following test function:

var
  item: Variant;
  list: Variant;
begin
  TDocVariant.New(item, [dvoIsObject]);
  TDocVariantData(list).Init([dvoIsArray]);
  for var idx: Integer := 0 to 100 do
  begin
    item.id := idx;
    item.source := StringToUtf8('source' + idx.ToString);
    item.target := StringToUtf8('target' + idx.ToString);
    TDocVariantData(list).AddValue(StringToUtf8('edge' + idx.ToString), item, True);
  end;
  FileFromString(TDocVariantData(TDocVariantData(list).ReduceAsArray('source')).ToCsv, '_testData.csv');

In the following source code IsArray prevents any further execution.

procedure TDocVariantData.ReduceAsArray(const aPropName: RawUtf8;
  var result: TDocVariantData; const OnReduce: TOnReducePerItem);
var
  ndx: PtrInt;
  item: PDocVariantData;
  v: PVariant;
begin
  TVarData(result) := DV_FAST[dvArray];
  if (VCount <> 0) and
     (aPropName <> '') and
     IsArray then

If you rewrite the selection as follows, you can see the problem.

  if VCount = 0 then Exit;
  if aPropName = '' then Exit;
  if not IsArray then Exit;

If IsArray is commented out, you get the desired result.

With best regards
Thomas

Offline

#2 2022-05-11 09:38:20

radexpol
Member
From: Poland, Krk
Registered: 2019-11-29
Posts: 116

Re: Problem with ReduceAsArray()

Instead of 

for var idx: Integer := 0 to 100 do

you can use

for var idx := 0 to 100 do

Offline

#3 2022-05-11 10:24:25

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,206
Website

Re: Problem with ReduceAsArray()

ReduceAsArray() works on an array of objects, not an object.

Your AddValue() call transforms list into an object.

Offline

#4 2022-05-11 11:41:43

tbo
Member
Registered: 2015-04-20
Posts: 335

Re: Problem with ReduceAsArray()

ab wrote:

ReduceAsArray() works on an array of objects, not an object.

Your AddValue() call transforms list into an object.

Now that I've stepped through the source code one by one, I've noticed it. With the following it works as it should:

TDocVariantData(list).AddItem(item);

Thanks for the hint.

radexpol wrote:

Instead of

for var idx: Integer := 0 to 100 do

you can use

for var idx := 0 to 100 do

I know that, but this magic feels a little weird to me. I am too old for that. wink

With best regards
Thomas

Offline

Board footer

Powered by FluxBB