reduce

Syntax

reduce(func, X, [init], [assembleRule|consistent=false])

reduce:T(X, [init]) or [init] <operator>:T X, where assembleRule is not specified and the default value is used.

reduce:TC(X, [init]) or [init] <operator>:TC X, where assembleRule is specified as C (for "Consistent") as an example.

Arguments

func is a function.
  • When func is a unary function, X can be a non-negative integer, a unary function, or a null value. init must be specified, which is the parameter of func.

  • When func is a binary function, X can be vector/matrix/table. init is the initial value.

  • When func is a ternary function, X must be a tuple with 2 elements, representing the last two parameters of func.

assembleRule (optional) indicates how the results of sub-tasks are merged into the final result. It accepts either an integer or a string, with the following options:
  • 0 (or "D"): The default value, which indicates the DolphinDB rule. This means the data type and form of the final result are determined by all sub results. If all sub results have the same data type and form, scalars will be combined into a vector, vectors into a matrix, matrices into a tuple, and dictionaries into a table. Otherwise, all sub results are combined into a tuple.

  • 1 (or "C"): The Consistent rule, which assumes all sub results match the type and form of the first sub result. This means the first sub result determines the data type and form of the final output. The system will attempt to convert any subsequent sub results that don't match the first sub result. If conversion fails, an exception is thrown. This rule should only be used when the sub results' types and forms are known to be consistent. This rule avoids having to cache and check each sub result individually, improving performance.

  • 2 (or "U"): The Tuple rule, which directly combines all sub results into a tuple without checking for consistency in their types or forms.

  • 3 (or "K"): The kdb+ rule. Like the DolphinDB rule, it checks all sub results to determine the final output. However, under the kdb+ rule, if any sub result is a vector, the final output will be a tuple. In contrast, under the DolphinDB rule, if all sub results are vectors of the same length, the final output will be a matrix. In all other cases, the output of the kdb+ rule is the same as the DolphinDB rule.

Note:
  • Starting from version 2.00.15/3.00.3, the new assembleRule parameter has been introduced. This parameter not only incorporates all the functionality of the original consistent parameter but also offers additional options for combining results.

    The consistent parameter is a boolean value that defaults to false, which is equivalent to setting assembleRule="D". When set to true, it’s equivalent to assembleRule="C". For backward compatibility, users can still use the consistent parameter. If both assembleRule and consistent are specified in the same operation, the value of consistent takes precedence.

  • assembleRule can also be specified after a function pattern symbol, represented by characters D/C/U/K (e.g., sub:PU(X). If not specified, the default value D will be used.

Details

The function of reduce is the same as accumulate. Unlike the template accumulate that returns result of each iteration, the template reduce outputs only the last result. Refer to accumulate for more information.

result=<function>(init,X[0]);
for(i:1~size(X)){
result=<function>(result, X[i]);
}
return result;

Examples

When func is a unary function:

// define a unary function
def func1(x){
  if(x<5){
          return x*3
  }
  else{
          return x+3
  }
}

// when X is an integer, iterate for X times
reduce(func1, 5, 1)
// output: 18

// when X is a unary function condition, the 3rd iteration stops as the condition returns false
def condition(x){
  return x<9
}
reduce(func1, condition, 1)
// output: 9

// when X is NULL or unspecified, define a UDF func2 for iteration
def func2(x){
  if(x<5){
          return x*3
  }
  else{
          return 6
  }
}

//As the results of the 3rd and 4th iterations are the same, the function stops iteration and outputs the result
reduce(func2,NULL,1)
// output: 6

When func is a binary function, and X is a vector:

reduce(mul, 1..10);
// factorization of 10
// output: 3628800

// the corresponding accumulate template for the operation above
*:A 1..10;
// output: [1,2,6,24,120,720,5040,40320,362880,3628800]

2 *:T 1..10;
// output: 7257600

def f1(a,b):a+log(b);
reduce(f1, 1..5, 0);
// output: 4.787492

reduce on a matrix:

x=1..12$3:4;
x;
col1 col2 col3 col4
1 4 7 10
2 5 8 11
3 6 9 12
+ :T x;
// output: [22,26,30]

When func is a ternary function:

def fun3(x,y,z){
  return x+y+z
}
reduce(fun3,[[1,2,3],[10,10,10]],5)
// output: 41