Skip to Content

The more I thought about Karol Kalisz’s creative BIAL example (How to get “Top X” our of resultset) to calculate Top/Bottom 5 rankings, the more annoyed I got that there’s not an easier way.  🙂   In hindsight, my approach might only be slightly more scalable, but at the cost of SDK voodoo.  I figured I’d try my hand at a component that’s just a .ZTL set of methods and see what happens all the same.  Here are the results!

To clarify “a little less code” is after writing more code for the sake of less later, if you do a lot of ranking scenarios.

The component is called ‘Collection’ and has one String property called ‘items’.  In reality, it’s just a storage medium for a JSON structure.

So going by Karol’s BIAL, I knew I’d need labels and values, so my idea of a structure was an Array of structured objects with labels and values:


[
     {label : "Apples", value : 10},
     {label : "Oranges", value : 5},
     {label : "Bananas", value : 20},
     {label : "Kiwis", value : 2}
]





This should be enough to keep track of changes as I sort.  What I ended up with was just basically a bunch of ZTL methods to do what we cannot do in BIAL:


class com.sample.utilities.Collection extends Component {
  void setItems(/*labels*/ String labels, /*values*/ String values) {*
  var items = [];
  var l = labels.split(",");
  var v = values.split(",");
  while(l.length<v.length) l.push("");
  while(v.length<l.length) v.push("0");
  for(var i=0;i<l.length;i++){
  items.push({
  label : l[i],
  value : v[i]
  })
  }
  this.items = JSON.stringify(items);
  *}
  String getLabels() {*
  var s = this.items;
  var items = eval(s);
  var a = [];
  for(var i=0;i<items.length;i++){
  a.push(items[i].label);
  }
  return a.join(",");
  *}
  String getValues() {*
  var s = this.items;
  var items = eval(s);
  var a = [];
  for(var i=0;i<items.length;i++){
  a.push(items[i].value);
  }
  return a.join(",");
  *}
  void sortByLabel() {*
  var s = this.items;
  var a = eval(s);
  a.sort(function(a,b){
  return a.label>b.label;
  });
  this.items = JSON.stringify(a);
  *}
  void sortByLabelDescending() {*
  var s = this.items;
  var a = eval(s);
  a.sort(function(a,b){
  return (b.label>a.label);
  });
  this.items = JSON.stringify(a);
  *}
  void sortByValue() {*
  var s = this.items;
  var a = eval(s);
  a.sort(function(a,b){
  var newA = parseFloat(a.value);
  var newB = parseFloat(b.value);
  return newA-newB;
  });
  this.items = JSON.stringify(a);
  *}
  void sortByValueDescending() {*
  var s = this.items;
  var a = eval(s);
  a.sort(function(a,b){
  var newA = parseFloat(a.value);
  var newB = parseFloat(b.value);
  return newB-newA;
  });
  this.items = JSON.stringify(a);
  *}
  void sortByValue() {*
  var s = this.items;
  var a = eval(s);
  a.sort(function(a,b){
  var newA = parseFloat(a.value);
  var newB = parseFloat(b.value);
  return newA-newB;
  });
  this.items = JSON.stringify(a);
  *}
  int getLength() {*
  var s = this.items;
  var a = [];
  if(s!="") a = eval(s);
  return a.length;
  *}
  String getLabel( /* index */ int index) {*
  var s = this.items;
  var a = eval(s);
  var r = "Blank";
  if(a.length>index){
  r = a[index].label;
  }
  return r;
  *}
  String getValueAsString( /* index */ int index) {*
  var s = this.items;
  var a = eval(s);
  var r = "Blank";
  if(a.length>index){
  r = a[index].value;
  }
  return r;
  *}
  float getValue( /* index */ int index) {*
  var s = this.items;
  var a = eval(s);
  var r = 0.0;
  if(a.length>index){
  r = a[index].value;
  }
  return r;
  *}
}





As you can see, we can set items and sort by either label or value, ascending or descending.  So what would the BIAL look like in context?

We can stage up some dummy data with a BIAL command like this:


COLLECTION_1.setItems(
  "Apples,Oranges,Bananas,Kiwi",
  "10,100,45,4"
);





Or, we can do a test with a data source:

/wp-content/uploads/2014/09/bial_539962.png

(Syntax highlighting in this blog kept messing up, so here’s a screenshot of the code)

And finally, I have a button that will sort the collection either ascending or descending:

/wp-content/uploads/2014/09/sortbial_540065.png

I’m still annoyed that I can’t do a simple for loop in BIAL, but whatever 🙂 – For each additional ranking it’s only one extra line of code.

Here’s the end result of the exercise:

/wp-content/uploads/2014/09/sorted_540066.png

And a sample with the dummy unit test without ugly green blocks 🙂 :  Note the “Blank” entry because there are less items than 5 so it even does some graceful failing 🙂 – This is an example of Bottom 5 because reverse is unchecked.

/wp-content/uploads/2014/09/sorted_testdata_540067.png

Full source will be available next time I update my Utility Pack.  Will update this entry when that happens but 95% of the work happens in the .ZTL file.  This was the first time I bothered doing a lot of the logic in the ZTL and I must say it’s not as bad after you know where the Java signature stops and the JavaScript begins 🙂

Enjoy!

To report this post you need to login first.

3 Comments

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

  1. Karol Kalisz

    Michael, this is very good idea, I even think it will be possible to return in a method something (a JSON) which will match the ZTL API for setItems()..

    when you place this at your GItHub, I can try to make the experiment. if successfull, I will give you the “extension” code for the collection.

    @Michael Howles  and @Mustafa Bensan – tree developers are always better than one!

    (0) 
    1. Mike Howles Post author

      Thanks for the feedback, Karol – In terms of source code, basically it’s the .ZTL code.  I’ll work on getting my utility pack cleaned up but my working version is littered with a bunch of experimental junk that I’ll want to remove before posting the version that contains this ZTL component.  That might be a few days until I can focus on the task.  In other words, you can probably run with what I pasted if you want to experiment!

      (0) 

Leave a Reply