Sun May 22, 2022 6:55 am
Login Register Lost Password? Contact Us

Constructing records from combinations of text fragments.

Questions around writing code and queries

Thu Nov 28, 2019 1:37 pm Change Time Zone


I expect this is posted else where as this seems a straightforward question, but given a variable number of text fragments (with a known final position in the record) how does one generate all records for every combination?
Code: Select all
Field Position     Text
1                  Allan
1                  Nina
2                  5
2                  6
2                  7
3                  ABC

Produces 6 records:

Code: Select all

The number of fields is also variable

In languages that allow recursion this is straightforward, but in ECL one can't reference a function from within itself. I've investigated LOOP but drawn a blank.
(Hum something like LOOP where the input record structure holds both the input child datasets AND the resultant string, slowly adding to the output and removing records from the child datasets until all child datasets are all empty????)

Thanks in advance

Posts: 444
Joined: Sat Oct 01, 2011 7:26 pm

Fri Nov 29, 2019 3:08 pm Change Time Zone

An elegant solution from Tony Kirk,
One has to remember that the next iteration to LOOP holds what’s constructed in the previous iteration, |Tony's also incremented the field number it's joining on as you go along.
Code: Select all
rIn  :=
  unsigned2  FieldPos;
  string     TextValue;
dIn  := dataset([{1, 'Allan'},
                 {1, 'Nina'},
                 {2, '5'},
                 {2, '6'},
                 {2, '7'},
                 {3, 'ABC'},
                 {3, 'DEF'},  // Added these
                 {4, '1A'},
                 {4, '2B'}
                ], rIn

rIn  tJoin(rIn pLeft, rIn pRight) :=
  self.FieldPos  :=  pRight.FieldPos;  // Sets up for next JOIN
  self.TextValue :=  trim(pLeft.TextValue) + if(pRight.FieldPos <> 0, ',' + trim(pRight.TextValue), '');  // both TRIMs probably redundant
fJoin(dataset(rIn) pStartDataset, unsigned2 pLeftFieldPos) := join(pStartDataset, dIn,
                                                                   left.FieldPos = pLeftFieldPos and right.FieldPos = left.FieldPos + 1,
                                                                   tJoin(left, right)

// REQUIRES FieldPos values start with 1 and have no gaps (didn't test what happens if 1 only).  Otherwise,
//   it would require prep to align low value with 1 and each subsequent iterated value one higher and use *that* MAX.
lLoopCount :=  max(dIn, FieldPos) - 1;
dLoop      :=  loop(dIn, lLoopCount, fJoin(rows(left), counter)); // Form 1 of LOOP


Nice one Tony
Posts: 444
Joined: Sat Oct 01, 2011 7:26 pm

Return to Programming

Who is online

Users browsing this forum: No registered users and 1 guest