Skip to end of metadata
Go to start of metadata

When dealing with data, iteration is important. KRL supports implicit and explicit looping:

  • First, recognize that the entire ruleset can be seen as a big if-statement looping over the event stream. Seeing event processing as a looping process helps design efficient, effective rulesets.
  • Also, JPexs provide a way of processing arrays in large data sets that amounts to a kind of implicit looping in many cases.
  • Many of the array and map operators like map() and filter() loop over data. 
  • In addition to these implicit forms of looping, KRL functions support recursion and thus can be used to iterate over arguments.

But with all that, we sometimes need explicit loops. KRL loops are a little different than what your previous programming experience might lead you to expect. The KRL foreach statement can only appear just below the select statement like so:

This statement would execute the entire rule three times with the variable x bound to 1, 2, and 3 in each successive execution.

The value following the keyword foreach can be any KRL expression that yields an array or map.  If the variable f were bound to a JSON data structure, you could use a pick and JPex like so:

To use the foreach statement with a map, you provide two variables in the setting clause that will be bound the name and value of that entry in the map:

This would bind a, b, and c to n along with 1, 2, and 3 to v on each successive iteration through the loop.

You can have more than one loop in a rule by simply nesting one foreach inside another:

As you’d expect, this would bind a, b, and c to y while x is 1, and then bind ab, and c to y while x is 2, and so on.  Since values being iterated over can be computed, you could use x in computing the array for the second loop.

At first it may seem restrictive to only be able to loop at the start of a rule, but it fits the rule model very nicely.  Because of their structure, rules in KRL become what are called FLWOR (pronounced “flower”) statements. FLWOR is an acronym for “Foreach, Let, Where, Order, Result.” The following table shows which KRL rule features plays which part in creating FLWOR statements.

Comparison of FLWOR and KRL

FLWORKRL
ForeachForeach
LetPrelude
WhereRule condition
OrderArray filters and operations
ResultAction

The entire rule body—everything after the select—is executed once for every loop. If the rule condition is true, an action is produced, so a rule with a foreach over a three-element array would produce three actions if the condition were true each time. (Note: KRL optimizes rule preludes by automatically moving expressions that don’t depend on the variable being set in the foreach statement outside the loop during execution so that only those things that really need to be executed multiple times are.)

When to Use a Loop

Your instincts might be to use foreach loops in places where it’s less efficient than using implicit looping. To see when you might want to use a JPex instead of a foreach statement let’s walk through an example. 

Suppose that you have a data set that lists a number of sites by URL and gives some data about each of them. Further, suppose you’d like to annotate sites with the data out of the dataset when the URL matches so that you don’t have to republish the ruleset each time it changes.

While this kind of data would generally be generated, let’s just declare it, in a variable named items, in the global:

Using this data, we want to place a notification box on any of the three sites listed in the page field. The notification uses the content and header data out of the dataset for any give page.

Your first attempt, using foreach might look something like this:

This does the job, looping through each item (binding its value to d) and using the premise of the rule to check that the current domain is applicable before placing the notification.

The problem is that this rule is quite inefficient. We’re looping through the data and throwing all the work away in all but one case (where the domain name matches the site we’re on).  For three items, this isn’t a big problem, but what if the data set contained information for thousands of sites? We’d be wasting a lot of processing time. There are two ways to solve this problem.

The first is to use the full power of array filters to cut the array down to just those members meeting the desired criterion:

The anonymous function in the filter() operator compares the page in its argument to the domain of the page the rule is running against. You could also define this function earlier in the global block and just give its name as an argument to filter. 

In this rule, the array will be filtered to only those items that have a page name that matches the domain of the current page. For our example, that would be an array of one. Consequently, the foreach isn’t really looping, it’s running once. This points us to the second way of making our rule more efficient: don’t use a foreach statement at all.

In the following rule, we use the implicit looping and filtering capabilities of a JPex to find just the item we want from the data structure and then pick the pieces we need out of that one item.

This rule uses the domain in constructing the JPex to select the right element of the array of items. The JPex is the secret to how the above rule works: the JPex does an implicit loop over the data and only selects the items where page matches the domain. Consequently, we don’t need the foreach.

Loops Drive Multiple Actions

As we’ve seen, foreach causes the same rule to be fired multiple times in a single ruleset evaluation. Some actions are better suited to use inside a foreach loop than others. For example, issuing multiple redirect() actions from a single rule doesn’t usually make sense. But other actions like append(), replace(), send_directive(), and so on are often done over and over with different data. An example illustrates this idea.

Suppose we wanted to make changes to a page based on data we retrieved from an online datasource. Assume the datasource returns data like the following and we bind it to a variable named replacements:

In this dataset, we have an array of replacements, each of which contains a jQuery selector pattern for elements on a Web page and the text we’re going to use with the action. The following ruleset uses the items in this data structure to prepend the text in each item above to the element on the page that matches the associated selector pattern:

This changes the same page multiple times according to the content of the data structure. Change the data and the behavior of the rule will follow. 

Using data often requires loops. We'v seen that there are multiple ways to loop in KRL: a ruleset is a loop, each rule can loop explicitly using foreach, and implicit looping is accomplished using operators like pick(), map(), and filter().

 

  1. Jun 12, 2012

    Anonymous

    Thanks for your publish. My souspe and i have generally seen that most people are desirous to lose weight because they wish to look slim in addition to looking attractive. However, they do not constantly realize that there are more benefits for you to losing weight as well. Doctors say that over weight people are afflicted with a variety of conditions that can be instantly attributed to their own excess weight. The good news is that people who\'re overweight plus suffering from diverse diseases can reduce the severity of the illnesses by way of losing weight. It is easy to see a continuous but noticeable improvement in health as soon as even a slight amount of losing weight is reached.One thing I\'d like to reply to is that weightloss system fast can be achieved by the appropriate diet and exercise. Ones size not just affects the look, but also the complete quality of life. Self-esteem, despression symptoms, health risks, and also physical abilities are afflicted in an increase in weight. It is possible to do everything right whilst still having a gain. If this happens, a problem may be the offender. While a lot food rather than enough physical exercise are usually guilty, common health conditions and widespread prescriptions may greatly help to increase size. Thanks for your post right here.I realized more new things on this weight-loss issue. 1 issue is a good nutrition is tremendously vital if dieting. A tremendous reduction in fast foods, sugary foodstuff, fried foods, sugary foods, beef, and whitened flour products could possibly be necessary. Retaining wastes parasites, and harmful toxins may prevent targets for losing fat. While specified drugs momentarily solve the problem, the horrible side effects aren\'t worth it, and in addition they never give more than a short lived solution. It is a known undeniable fact that 95% of celebrity diets fail. Thank you for sharing your notions on this blog site.Thanks for the recommendations shared in your blog. Yet another thing I would like to mention is that weight reduction is not all about going on a dietary fad and trying to lose as much weight as possible in a few days. The most effective way to shed weight is by consuming it slowly and gradually and using some basic guidelines which can make it easier to make the most through your attempt to lose fat. You may learn and be following some of these tips, but reinforcing know-how never does any damage.I believe avoiding highly processed foods will be the first step to be able to lose weight. They can taste excellent, but processed foods currently have very little vitamins and minerals, making you take more only to have enough energy to get throughout the day. In case you are constantly consuming these foods, changing to cereals and other complex carbohydrates will let you have more energy while consuming less. Thanks a lot : ) for your blog post.