Hi,
I have a process variable CDT of type array, the CDT has this fields {Title1=,Title2=,Title3=}.
And i have an array with the values {3,4,7,q,a,1,3,9,0}.
And i want to have the PV populated like this: {{Title1=3,Title2=4,Title3=7},{Title1=q,Title2=a,Title3=1},{Title1=3,Title2=9,Title3=0}}
Do you have any suggestions?
It has to be a flexible solution because it has to be used with different CDT's, on the process.
Thanks
Discussion posts and replies are publicly visible
The code below will give you the expected output for the provided input, but the part about it being generic enough to work with any CDT is a lot trickier. Maybe you can define a rule like the example here for each of the CDTs you know about right and then create a wrapper rule that will act as a dispatcher.
= load( /* ri!data is List of Text String, ri!fieldCount is Integer */ local!count: count(ri!data)/ri!fieldCount, a!forEach( enumerate(local!count), { Title1: index(ri!data, 1+ri!fieldCount*fv!item, null), Title2: index(ri!data, 2+ri!fieldCount*fv!item, null), Title3: index(ri!data, 3+ri!fieldCount*fv!item, null) } ))
One thought I'd had is if the CDT fields are known, maybe we could pass them in as an array too.
It can be tricky to dynamically name the dictionary field names, but one trick I've seen used before is to manually construct a JSON string and then back-translate that to actual dictionary data. I've had moderate success so far with this approach (note the rule inputs here are "fields" and "data", both text strings):
with( local!numFields: length(ri!fields), /* for the count we need to do "ceiling" on the division result or else we risk truncating any remainders in the data array. doing it this way, the data array doesn't need to be an even multiple of the number of fields. */ local!count: ceiling(count(ri!data) / local!numFields), local!jsonString: "[" & joinarray( a!foreach( enumerate(local!count), with( /* i assume this is the only way we can access the fv!item value from inside the lower nested a!forEach call - pretty painless at the end of the day but it took me a while to figure out to try this */ local!cdtCount: fv!item , "{" & joinarray( a!forEach( ri!fields, """" & fv!item & """:""" & index( ri!data, local!cdtCount * local!numFields + fv!index, null() ) & """" ), "," ) & "}" ) ), "," ) & "]", a!fromJson( local!jsonString ))
Side note 1: a!forEach really is a savior.Side note 2: you really want to use with() instead of load() in this rule, at least if it ever has even the slightest chance of being called from a SAIL form or anything, because load() will cause weird side-effects that catch someone off-guard.
Just create a new rule with the body of the a!forEach function, and pass that to apply
a!forEach
apply