You are not logged in.
From a TDocVariantData object, I would like to split its properties into new instances.
For example, initiate a DocVariantData (dv for short) using this JSON:
{"obj:"{"id:1,"text":"blabla"}}
name = "obj"
value = {"id":1,"text":"blabla"}
I can iterate the dv using its enumerator:
var
dv: TDocVariantData;
pair: TDocVariantFields;
begin
if dv.InitJson('{"obj:"{"id":1,"text":"blabla"}}', JSON_FAST_FLOAT) then
begin
for pair in dv do
begin
// here pair.Value^ will contain {"id:1,"text":"blabla"}
// now, how can I create two new PDocVariantData objects...
// 1 = {"id":1}
// 2 = {"text":"blabla"}
// ...but both sharing the same data from dv ?
end;
end;
end;
I haven't found any _Obj* function or TDocVariantData.Method to do that.
Maybe a new _ObjFast(PRawUtf8, PValue) or so could be create?
Thanks.
Last edited by mdbs99 (2023-02-22 20:03:33)
Offline
I am not sure what "sharing the same data" means exactly.
You could use a new TDocVariantData with values as vtPointer, pointing to the variant values of the main dv.
But it may quickly be error prone (random GPF if the user does not take care of the instances lifetime), or un-shared for some kind of values (numbers are likely to be copied by value not by reference during copy).
And it would be one-way: only reflecting the changes in the main dv, not any change from the flattened objects.
Offline
"sharing the same data" means that all (sub)objects will point to the same data of the main object.
Currently, I can do that using arrays, creating new objets for each index and those objects points to the main data.
For example, we can split an array of objects, creating new objects for each item, then changing any value on those subobjects it will change the main array data:
var
vDoc: TDocVariantData;
vIndex1: PDocVariantData;
begin
vDoc.Clear;
if vDoc.InitJson('[{"id":1,"text":"blabla"},{"id":2,"text":"toto"}]', JSON_FAST_FLOAT) then
begin
ShowMessage(vDoc.ToJson);
vIndex1 := _Safe(vDoc.Value[1]);
vIndex1^.S['text'] := 'new value'; // shared data; it will change both object
ShowMessage(vDoc.ToJson);
ShowMessage(vIndex1^.ToJson);
end
else
ShowMessage('invalid json');
end;
Following the same idea, it would be nice if we could split an object, creating new objects for each property of the main one — but sharing the data, of course.
Offline
vIndex1 points to vDoc.Value[1] as a direct pointer.
It does not share the data, it is just the same data.
If you want to create another TDocVariantData to hold the values, it won't be a direct pointer.
At most, it could be a vtPointer kind of variant.
Which is not the same: if you change the value in the 2nd TDocVariantData, it won't be reflected on the first/main TDocVariantData.
Offline
vIndex1 points to vDoc.Value[1] as a direct pointer.
It does not share the data, it is just the same data.
In this case, same data or sharing the data is the same to me. But, Ok, we're at the same page.
If you want to create another TDocVariantData to hold the values, it won't be a direct pointer.
At most, it could be a vtPointer kind of variant.
Which is not the same: if you change the value in the 2nd TDocVariantData, it won't be reflected on the first/main TDocVariantData.
What doesn't work for me
Offline