Access record fields positionally

Hello,

I am trying to write a denormalizer CTL which is capable of executing against any edge metadata. In other words, the CTL logic doesn’t need to explicitly call out field names – it can work regardless of the meta data on the edge.

This particular denormalizer has the same metadata on the input edge and output edge and aims to “combine” the output records by ID and delimiting the unique values as such:

Data on the input port:

ID|DESC1|DESC2
1|Good|Red
1|Average|Blue
2|Expensive|Blue
3|Very Expensive|Red
3|Height|Blue
3|Weight|Blue

Data on the output port:

ID|DESC1|DESC2
1|Good,Average|Red,Blue
2|Expensive|Blue
3|Very Expensive,Height,Weight|Red,Blue

I am able to do this if I am explicit in my field names, e.g.

//#CTL2
//TL
// This transformation defines the way in which multiple input records 
// (with the same key) are denormalized into one output record. 

// local variables
string id;
string desc1;
string desc2;

// This function is called for each input record from a group of records
// with the same key.
function integer append() {
		
	id = $0.ID;
	//if the new value isn't already in the delimited list, add it.
	if (indexOf(desc1,$0.DESC1) == -1) {
		desc1 = desc1 + iif(length(desc1) > 0 ,",","") + $0.DESC1;
	}
	
	// if the new value isn't already in the delimited list, add it.
	if (indexOf(desc2,$0.DESC2) == -1) {
		desc2 = desc2 + iif(length(desc2) > 0 ,",","") + $0.DESC2;
	}

	return OK;
}

// This function is called once after the append() function was called for all records
// of a group of input records defined by the key.
// It creates a single output record for the whole group.
function integer transform() {
  
  $0.ID = id;
  $0.DESC1 = desc1;
  $0.DESC2 = desc2;

  return OK;
}

// Called after transform() to return the resources that have been used to their initial state
// so that next group of records with different key may be parsed.
function void clean() {
	id = "";
	desc1 = "";
	desc2 = "";
}

But as I try to make my CTL field-name agnostic, I am having trouble with the correct syntax and am not finding much in the online resources or CTL language guide (but, I admit, I don’t know all the resources yet so I may just be looking in the wrong spots). Here is what I have attempted:

//#CTL2
//TL
// This transformation defines the way in which multiple input records 
// (with the same key) are denormalized into one output record. 

// local variables
string id;
string desc1;
string desc2;
recordName2 myrec1;
string[] fieldList;

// This function is called for each input record from a group of records
// with the same key.
function integer append() {
		
	id = $0.ID;
	myrec1 = $0; // <--  HOW DO I ASSIGN THE INCOMING RECORD?
	
	for(integer i = 1; i < length(myrec1); i++) {
		if (indexOf(fieldList[i],myrec1[i]) == -1 && getFieldName(myrec1,i) != "ID") { //<-- HOW DO I ACCESS FIELDS ON MY RECORD POSITIONALLY, LIKE AN ARRAY?
			fieldList[i] = fieldList[i] + iif(length(fieldList[i]) > 0 ,",","") + myrec1[i];
		}
	}
	
	return OK;
}

// This function is called once after the append() function was called for all records
// of a group of input records defined by the key.
// It creates a single output record for the whole group.
function integer transform() {
  
  for(integer j = 1; j < length(fieldList); j++) {
  	if(getFieldName(myrec1,j) != "ID") {
  		$0 =  fieldList[j]; //<-- HOW DO I OUTPUT MY FIELDS POSITIONALLY?
  	}
  }
  
  $0.ID = id;

  return OK;
}

// Called after transform() to return the resources that have been used to their initial state
// so that next group of records with different key may be parsed.
function void clean() {
	id = "";
	fieldList = null;
}

Anyone have any thoughts? Can you show me how to do this syntactically?

Hello,
unfortunately CTL still not allows to attend output fields by indexes, but the transformation can be easily written in java (see attached file)

Thanks Agata! This worked like a charm!