The third form uses a TRANSFORM function to produce its single record result. The transform function must take at least one parameter: a LEFT record, which must be in the same format as the input record. The format of the resulting record may be different from the input.
Example:
IMPORT Std;
NameRec := RECORD
STRING5 title;
STRING20 fname;
STRING20 mname;
STRING20 lname;
STRING5 name_suffix;
STRING3 name_score;
END;
MyRecord := RECORD
UNSIGNED id;
STRING uncleanedName;
NameRec Name;
END;
x := DATASET('RTTEST::RowFunctionData', MyRecord,THOR);
STRING73 CleanPerson73(STRING inputName) := FUNCTION
suffix:=[ ' 0',' 1',' 2',' 3',' 4',' 5',' 6',' 7',' 8',' 9',
' J',' JR',' S',' SR'];
InWords := Std.Str.CleanSpaces(inputName);
HasSuffix := InWords[LENGTH(TRIM(InWords))-1 ..] IN suffix;
WordCount := LENGTH(TRIM(InWords,LEFT,RIGHT)) - LENGTH(TRIM(InWords,ALL))+1;
HasMiddle := WordCount = 5 OR (WordCount = 4 AND NOT HasSuffix) ;
Space1 := Std.Str.Find(InWords,' ',1);
Space2 := Std.Str.Find(InWords,' ',2);
Space3 := Std.Str.Find(InWords,' ',3);
Space4 := Std.Str.Find(InWords,' ',4);
STRING5 title := InWords[1..Space1-1];
STRING20 fname := InWords[Space1+1..Space2-1];
STRING20 mname := IF(HasMiddle,InWords[Space2+1..Space3-1],'');
STRING20 lname := MAP(HasMiddle AND NOT HasSuffix =>
InWords[Space3+1..],
HasMiddle AND HasSuffix =>
InWords[Space3+1..Space4-1],
NOT HasMiddle AND NOT HasSuffix =>
InWords[Space2+1..],
NOT HasMiddle AND HasSuffix =>
InWords[Space2+1..Space3-1],
'');
STRING5 name_suffix := IF(HasSuffix,InWords[LENGTH(TRIM(InWords))-1 ..],'');
STRING3 name_score := '';
RETURN title + fname + mname + lname + name_suffix + name_score;
END;
//Example 1 - a transform to create a row from an uncleaned name
NameRec createRow(string inputName) := TRANSFORM
cleanedText := CleanPerson73(inputName);
SELF.title := cleanedText[1..5];
SELF.fname := cleanedText[6..25];
SELF.mname := cleanedText[26..45];
SELF.lname := cleanedText[46..65];
SELF.name_suffix := cleanedText[66..70];
SELF.name_score := cleanedText[71..73];
END;
myRecord t(myRecord L) := TRANSFORM
SELF.Name := ROW(createRow(L.uncleanedName));
SELF := L;
END;
y := PROJECT(x, t(LEFT));
OUTPUT(y);
//Example 2 - an attribute using that transform to generate the row.
NameRec cleanedName(STRING inputName) := ROW(createRow(inputName));
myRecord t2(myRecord L) := TRANSFORM
SELF.Name := cleanedName(L.uncleanedName);
SELF := L;
END;
y2 := PROJECT(x, t2(LEFT));
OUTPUT(y2);
//Example 3 = Encapsulate the transform inside the attribute by
// defining a FUNCTION structure.
NameRec cleanedName2(STRING inputName) := FUNCTION
NameRec createRow := TRANSFORM
cleanedText := CleanPerson73(inputName);
SELF.title := cleanedText[1..5];
SELF.fname := cleanedText[6..25];
SELF.mname := cleanedText[26..45];
SELF.lname := cleanedText[46..65];
SELF.name_suffix := cleanedText[66..70];
SELF.name_score := cleanedText[71..73];
END;
RETURN ROW(createRow); //omitted row parameter
END;
myRecord t3(myRecord L) := TRANSFORM
SELF.Name := cleanedName2(L.uncleanedName);
SELF := L;
END;
y3 := PROJECT(x, t3(LEFT));
OUTPUT(y3);
See Also: TRANSFORM Structure, DATASET, RECORD Structure, FUNCTION Structure