UIZE JavaScript Framework

2012 NEWS 2012-02-19 - NEW MODULE: Uize.Data.Combinations

The new Uize.Data.Combinations module provides methods for generating object or array combinations from a combination specifier, with support for an optional combination transformer and combination matcher.

The methods of the Uize.Data.Combinations module make it easy to produce a large set of combinations in a highly performant way.

1. Scalable

The Uize.Data.Combinations module is scalable in its ability to support an arbitrary number of combination properties.

Whereas a typical approach to producing combinations might involve nested for loop structures, this approach can only support a fixed number of properties and does not scale well to support an arbitrary or dynamic number of properties. The Uize.Data.Combinations module can support an arbitrary and also very large number of combination properties without trouble.

2. Performant

The Uize.Data.Combinations module is implemented to be highly performant, avoiding the use of recursion or the repeated creation and destruction of partial results sets.

The Uize.Data.Combinations module uses an approach much like generating all possible numbers up to a maximum number. In this way, the module can implement combination generation using just two levels of loop nesting, regardless of how many properties there are in the combination specifier. No recursion is used, thereby reducing function call overhead and call stack bloat.

3. The Methods

The Uize.Data.Combinations module provides the following static methods to deal with generated combinations...

Uize.Data.Combinations.forEach - lets you iterate through generated combinations, executing the specified iteration handler function for each combination
Uize.Data.Combinations.generate - produces an array containing the generated combinations

4. A Real World Example

In this example, we are using the Uize.Data.Combinations.generate method to generate an array of hex RGB color strings for the full palette of Web safe colors.

If we were to approach this problem the traditional way, we would write our code using three nested for loops - one for each of the three RGB color channels. This approach would produce code as follows...

THE TEDIOUS WAY

var
  channelValues = ['00','33','66','99','CC','FF'],
  webSafeColors = []
;
for (var redValueNo = 0; redValueNo < channelValues.length; redValueNo++) {
  for (var greenValueNo = 0; greenValueNo < channelValues.length; greenValueNo++) {
    for (var blueValueNo = 0; blueValueNo < channelValues.length; blueValueNo++) {
      webSafeColors.push (
        '#' +
        channelValues [redValueNo] +
        channelValues [greenValueNo] +
        channelValues [blueValueNo]
      );
    }
  }
}

If we instead use the Uize.Data.Combinations.generate method, we can reduce our code down to something more concise and elegant, as follows...

THE CONCISE WAY

var
  channelValues = ['00','33','66','99','CC','FF'],
  webSafeColors = Uize.Data.Combinations.generate (
    [channelValues,channelValues,channelValues],
    '"#" + value.join ("")'
  )
;

In our solution, we create the variable channelValues, whose value is an array representing all the possible values for a color channel in a Web safe color. We then use this possible values array in a combination specifier that provides a template for an RGB color tuple. Then, to ensure that the array of generated values is an array of hex formatted RGB color strings, we specify a combination transformer expression string that takes a generated combination tuple and joins its three elements and adds a "#" (pound character) prefix.

5. Comprehensively Documented and Tested

The Uize.Data.Combinations module is comprehensively documented and has exhaustive unit tests in the Uize.Test.Uize.Data.Combinations test module.