Arrays in RPE


The series started with JavaScript Objects in RPE continues with collections. This post covers using collections, more specifically arrays, sorting collections and an end to end example on using collections to manipulate live data:

  • read the data from a provider and store it in an array
  • sort the array on arbitrary rules
  • render the content of the array using an iteration element

In RPE collections can be used to solve many complex problems including but not limited to:

  • sorting not supported directly by RPE ( sorting on child properties)
  • combining data from multiple sources more easily/efficiently ( avoid repeated passes over the data)
  • restructuring the data ( avoid complex template nesting)

There are 2 types of collections you can use in RPE JavaScript: Java collections and JavaScript collections. Both can be used but as you will see in the following using JavaScript ones are the simpler solution in most cases.

Java Arrays

The Java arrays have more features and you have a many options when choosing an implementation. In my example I will be using ArrayList as it’s a fairly good all around implementation.

var arr = new java.util.ArrayList();

// populate the array
arr.add( "string 1");
arr.add( "string 2");
arr.add( "string 3");

// traverse the array
for ( i = 0; i < arr.size(); ++i)
{
    java.lang.System.out.println( arr.get( i));
}

The downside of using Java Arrays in the context of RPE scripts is their slightly more difficult usage. This is not obvious when using the arrays inside a single script expression but when you need to stored the in a template variable and manipulate them across multiple script expressions. The problem stems from the fact that RPE Document Studio does not have all the context at design time so the JavaScript interpreter used to verify the script expression at design time  does not know the type of the variable.

Script 1: create the array, populate it and store it in the varArray template variable

varArray = new java.util.ArrayList();
varArray.add( "string 1");
varArray.add( "string 2");
varArray.add( "string 3");

Script 2: print the array created in Script 1.

RPE Document Studio will complain when saving this expression since at this time Script 1 is not executed so varArray was yet to be created.

rpeactual_javaarrays

JavaScript Arrays

You can avoid the compilation errors when using Java arrays by using try&catch blocks and/or if conditions but in most cases the simpler solution is to use JavaScript Arrays.

var arr = [];

// populate the array
arr.push( "string 1");
arr.push( "string 2");
arr.push( "string 3");

// traverse the array
for ( i = 0; i < arr.length; ++i)
{
    java.lang.System.out.println( arr[i]);
}

Java Script arrays allow access to their content using the [] operator. Adding an element at the end of the array is done with the push function and removing the last element is done using the pop function. JavaScript arrays have a shortcut constructor that allows initializing the array immediately: arr = [“string 1”, “string 2”, “string 3”]

For more on the syntax and methods available for the Java Script arrays see W3Schools: JavaScript Arrays

Script 1: create the array, populate it and store it in the varArray template variable

if ( varArray == "")
{
  varArray = [];
}

 varArray.push( "string 1");
 varArray.push( "string 2");
 varArray.push( "string 3");
}

NOTE: the script that creates the array must also add at least 1 element to the array as RPE cannot distinguish between an empty string and an empty array.  If the array is empty when stored in the template variable RPE will use it as a string in the next script expression.

 Script 3: print the array

// traverse the array
for ( i = 0; i < varArray.length; ++i)
{
    java.lang.System.out.println( varArray[i]);
}

Sorting JavaScript arrays

A JavaScript array can be sorted using the sort function. The default behavior depends on the array elements but usually it is alphabetic and ascending.

You can change the sort rules by providing a comparison function as an argument of the sort function itself. The comparison function receives as parameters the 2 elements in the array it has to compare and must return:

  • a negative integer if o1 < o2
  • zero if o1 == o2
  • a positive integer if o1 > o2

Providing a comparison function also allows to compare on multiple properties of the data if the contents of the array are composite objects.

Example: the following string will sort the entries in the array based on their length.

 varArray = [];
 
 varArray.push( "abcdefgh");
 varArray.push( "qwerty");
 varArray.push( "xy");
 varArray.push( "z");

varArray.sort(function(o1, o2){
   return o1.length - o2.length
});

for ( i = 0; i < varArray.length; ++i)
{
    java.lang.System.out.println( varArray[i]);
}

End to end example

The last section of this article shows how to read several properties of the data, store them in JavaScript objects in an array, sort the array and then render it in an iteration.

The data used in the sample template is the ReqPro sample shipped with RPE in %RPE_HOME%\source\XML\examples. The sample, sampleJSArrays.zip,  is available in the RPE DevelopeerWorks Wiki.

Template outline

rpeactual_sampleTemplate

Script 1: read the data

if ( data_ == "")
{
   data_ = [];
}

var obj = new Object();
obj[ "tag"] = FullTag;
obj[ "text"] = Text;
obj[ "priority"] = Priority;

data_.push( obj);

Script 2: sort the requirements based on priority

NOTE: the sort can be made simpler if numeric values are assigned to the priority strings and those values are stored in the object alongside with the string value.

function compare( o1, o2)
{
  if ( o1[ "priority"] == o2["priority"])
  {
    return 0;
  }
  else  if ( o1[ "priority"] == "High")
  {
     return 1;
  }
  else   if ( o1[ "priority"] == "Medium" && o2[ "priority"] == "Low")
  {
     return 1;
  }
 
  return -1;
}

if ( data_ != "")
{
   data_.sort( compare);
}

Script 3: pick the current iteration element and render the desired property.

if ( data_ != "")
{
  var obj = data_[ current_*1];
  obj["tag"];
}

Output

rpeactual_output

Advertisements

Author: Dragos Cojocari

Architect for Rational Publishing Engine

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s