Update 29-Apr-2015: Added 2 examples for get values based on another field that matched condition string.

Update 27-Apr-2015: Added 7 examples for Handle leading and trailing zero and space trimming and padding, 2 example for Context handling.
Update 26-Apr-2015:
Added 2 examples for Delimited string to context values and the reverse way.
Update 25-Apr-2015:
Added DisplayQueue screenshots.


Introduction

UDF can be written for many different purpose, and with many different way of coding. Still, there should be some reusable coding/statement/patterns that keep on occurs again and again. In this document, is my attempt to list down some common coding/statement and patterns that known. Below meant to be building blocks, mean not use it standalone, and should mix and match with other building blocks to come out something useful. It just like LEGO

Category

Requirement

UDF coding

Condition

Test if input field existed (not null).

Normally this should be first checking for value, if null then do nothing.

if (value != null)

Condition

Test if context values existed (not null).

Normally this should be first checking for contextValues, if empty context(null) then do nothing.

if (contextValues != null && contextValues.length > 0)

Condition

Test if has value (non-empty). Normally if false, sub-sequence coding will return result with empty string only.

if (value != null && value.trim().length() > 0)

Condition

Test if value is suppress.

if (ResultList.SUPPRESS.equalsIgnoreCase(value)))

Condition

Test if value is context change.

if (ResultList.CC.equals(value))

ResultList

Add suppress to result.

result.addSuppress();

ResultList

Add context change to result.

result.addContextChange();

ResultList

Add value to result.

result.addValue(value);

ResultList

Add boolean true/false to result. Boolean value will be used in next function call.

result.addValue(“true”);
result.addValue(“false”);

ResultList

Add empty string to result. Empty string will create target node.

result.addValue(“”);

ArrayList

Create new array list.

List array = new ArrayList();

ArrayList

Add value to array.

array.add(value);

ArrayList

Test if array contains value.

if (array.contains(value))

Looping

Pattern

Single loop at contextValues, get each value to do something.

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

  //Do something
}

Looping

Pattern

Create target node if some condition is met.

Suggested function name:
createIf<SomeConditions>

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

 
  if(<SomeConditions is true>){

      result.addValue(“”);

  }

  else{

      result.addSuppress();

  }
}

Looping Pattern Pass value to target node if some condition is met.

Suggested function name:

passIf<SomeConditions>

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

 
  if(<SomeConditions is true>){

      result.addValue(value);

  }

  else{

      result.addSuppress();

  }
}

Looping Pattern

Return true if some condition is met, otherwise false.

Suggested function name:
has<SomeConditions>
is<SomeConditions>

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

 
  if(<SomeConditions is true>){

      result.addValue(“true”);

  }

  else{

      result.addValue(“false”);

  }
}

Looping Pattern

Return single true if some condition is met for values in context, otherwise single false.


Suggested function name:

contextHas<SomeConditions>
contextIs<SomeConditions>

String conditionMet = “false”;

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

 
  if(<SomeConditions is true>){

      conditionMet = “true”;

      break;

  }
}


result.addValue(conditionMet);

Looping Pattern Outer and inner loop at contextValues and secondContext, get both outer and inner value to compare and do something.

for (int i = 0; i < contextValues.length; i++){
  String value1 = contextValues[i];


  for (int j = 0; j < secondContext.length; j++){

      String value2 = secondContext[j];
      //Compare value1 and value2

      //Do something

  }
}

Position Get value from contextValues based on index/position.

Suggested function name:

getValueByIndex
getFirstValue

getLastValue

input1 = contextValues
input2 = index(optional, starting at 1)

by index –> result.addValue(contextValues[index-1]);
first –> result.addValue(contextValues[0]);

last –> result.addValue(contextValues[contextValues.length-1]);

Context

Split each value in contexts with context change. Simulate splitByValue(ForEach).

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

  result.addValue(value);

  if(i != contextValues.length – 1){

      result.addContextChange();

  }

}

Context

Remove all context change in contextValues. Simulate removeContext.

for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];

  if (!ResultList.CC.equals(value)){

      result.addValue(value);

  }

}

Context

Return only unique values, remove duplicated values.

List uniqueList = new ArrayList();


for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];


  if (!uniqueList.contains(value)) {

      uniqueList.add(value);

      result.addValue(value);

  }
}

Context Split input1 full string to context values by delimiter specified by input2.

input1 = fullString

input2 = delimiter


String dchar = delimiter[0];

for (int i = 0; i < fullString.length; i++){

  String[] splitString = fullString[i].split(dchar);

  for (int j = 0; j < splitString.length; j++) {

      result.addValue(splitString[j]);

  }

}

Context

Concatenate input1 context values to delimited string by delimiter specified by input2.

input1 =contextValues

input2 = delimiter

String fullString = “”;

String dchar = delimiter[0];


for (int i = 0; i < contextValues.length; i++){

  String value = contextValues[i];


  if(i == 0){

      fullString = value;

  }

  else{

      fullString = fullString + dchar + value;

  }

}

result.addValue(fullString);

Context Remove suppress, return only values

for (int i = 0; i < contextValues.length; i++) {

  String value = contextValues[i];


  if (!ResultList.SUPPRESS.equalsIgnoreCase(value)){

      result.addValue(value);

  }

}

Context

Generate single suppress. (useful for unit testing single function)

result.addSuppress();
Context

Combine 2 queues into 1 queue.

input1 = q1

input2 = q2

for (int i = 0; i < q1.length; i++) {

  result.addValue(q1[i]);

}

for (int i = 0; i < q2.length; i++) {

  result.addValue(q2[i]);

}

Context

If input1 condition values equal to input2 single condition string, then get corresponding value from input3 context values.

input1 = conditionValues
input2 = conditionString
input3 = contextValues

String condition = conditionString[0];

for (int i = 0; i < conditionValues.length; i++){

  if(conditionValues[i].equalsIgnoreCase(condition)){

      result.addValue(contextValues[i]);

  }

  else{

      result.addSuppress();

  }

}

Context

If input1 condition values equal to any input2 multiple condition string separated by semicolon, then get corresponding value from input3 context values.

input1 = conditionValues
input2 = conditionString
input3 = contextValues

String conditions[] = conditionString[0].split(“;”);


for (int i = 0; i < conditionValues.length; i++){

  boolean found = false;

  String value = “”;


  for(int j = 0; j < conditions.length; j++){

      if(conditionValues[i].equalsIgnoreCase(conditions[j])){

        value = contextValues[i];

        found = true;

        break;

      }

  }


  if(found){

      result.addValue(value);

  }

  else{

      result.addSuppress();

  }

}

Zero

Trim leading and trailing zero.

Using UDF:

FormatNum:

FormatNum can achieve this requirement. Below UDF remain as learning purpose only, please use standard FormatNum instead.


String output = “”;


output = value.replaceAll(“^0*”, “”);


Integer idx = value.indexOf(“.”);


if(idx != -1){

  output = output.replaceAll(“0*$”, “”).replaceAll(“\\.$”, “”);

}


if (output.trim().length() == 0) {

  output = “0”;

}


if(output.startsWith(“.”))

{

  output = “0” + output;

}


return output;

Space

Trim leading space at left side.

String output = value.replaceAll(“^\\s*”, “”);

return output;

Space

Trim trailing space at right side.

String output = value.replaceAll(“\\s*$”, “”);

return output;

Space Trim leading and trailing space.

Just use standard text trim() function.


Space Pad leading space up to total length.

input1 = value

input2 = totalLength

good short version:
return String.format(“%1$” + totalLength + “s”, value);

long version:

String output = value;

int toLength = Integer.parseInt(totalLength);

while (output.length() < toLength) {

            output = ” ” + output;

}

return output;

Space

Pad trailing space up to total length.

input1 = value

input2 = totalLength

good short version:

return String.format(“%1$-” + totalLength + “s”, value);

long version:

String output = value;

int toLength = Integer.parseInt(totalLength);

while (output.length() < toLength) {

            output = output + ” “;

}

return output;

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. Eng Swee Yeoh

    Yee Loon

    Some feedback on your latest additions.

    Trimming leading or trailing zeroes can already be achieved via standard function FormatNum if you specify the pattern according the Java’s DecimalFormat. This was already mentioned in a comment to a recent UDF-related blog (which is already removed because I guess it is no longer relevant). IMHO, best to stick with standard functions on this unless there is a specific pattern that cannot be achieved with them.

    For padding spaces, it can also be achieved by providing appropriate formatting (with Formatter) when using static method String.format(). Also, you can define the totalLength type as int so no parseInt() is not necessary. Refer sample below.

    private String padRight(String input, int width) {

    return String.format(“%1$-” + width + “s”, input);

    }

    Rgds

    Eng Swee

    (0) 
    1. Yee Loon Khoo Post author

      Hi Eng Swee,

      Thanks for feedback and the input. Agreed, use standard function whenever possible. Tested FormatNum and String.format() is working fine for both zeroes trimming and space padding. UDF document updated too with your input. Thx!

      Regards,

      Yee Loon

      (0) 

Leave a Reply