Lambda fold() examples

The typical use of the Lambda.fold() method takes three parameters:

  • An iterable (list or array) to act upon
  • A function used for processing the values in the iterable and returning a result value
  • A seed value to use as a starting point for the first iteration

    Adding values in a list


    A common use of fold() is to add the values in a list. Let's say we have the following array as our iterable:
    var items = [2, 3, 4];

We can then add them using fold() this way:

var result = Lambda.fold(items, function(itemA, itemB) {    
    trace([itemA, itemB]);
    return itemA + itemB;
}, 0);  // <-- Initial seed value, used for itemB in the very first iteration
trace('result: ' + result);

This gives the expected result 9.

Let's have a look of the trace output to see what just happened:
The trace output of the iterations should be

    [2, 0]
    [3, 2]
    [4, 5]

Note the following:
  • the values for itemA (the left column in the traced pairs - 2, 3 and 4) corresponds to the iterables list values [2, 3, 4]
  • the values for itemB (the right column in the traced paris - 0, 2 and 5) repersents the result of the addition calculation

However, note that the very first iteration, there is no processed value for itemB to handle - that's where the initial seed value comes into place.
Let's try a seed value of 100 to see the effect:

var result = Lambda.fold(items, function(itemA, itemB) {    
    trace([itemA, itemB]);
    return itemA + itemB;
}, 100);  // <-- Initial seed changed to 100
The trace output should now be
    [2, 100]
    [3, 102]
    [4, 105]

and the result value 109.

Processing objects in a list


The Lambda.fold() can be used in a handy way to process objects in an iterable where you have to keep track of two neighbour items.
The conventional way to do this is something like the following:
// pseudo code
var examples: Array<Example> = [ex1, ex2, ex3, ex4];
var prevEx:Example = null;
for (currentEx in examples) {
    if (prevEx== null) {  // Skip first iteration because the prevEx is null
        prevEx = currentEx;
        continue;
    }
    if (prevEx .foo && currentEx.foo) {  // here we have both currentExand prevEx present
        // do something
        currentEx.bar = 'BAR';
    }
    prevEx = currentEx;
}

Using Lambda.fold() to accomplish the same thing:

// pseudo code
var examples: Array<Example> = [ex1, ex2, ex3, ex4];
Lambda.fold(items, function(exA, exB) {
    if (exB== null) return exA;
    if (exA.foo && exB.foo) {  // here we have both exA and exBpresent
        // do something in this special case
        exA.bar = 'BAR';
    }    
    return exA;  // returning item to become the next exB
}, null);  // we're using null as seed value for exBthe first iteration

As you can see, we don't need to manually keep track of the prevItem object - the fold() method does it for us.

version #15334, modified 2012-08-13 09:26:59 by cambiata
0 comment