Implement DMAX and DSUM functions, following the pattern from DMIN.

Refactored the D* function enum to have instances return the function implementation instances rather than using a case construct, now that Java 8 is required.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1819376 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Greg Woolsey 2017-12-27 22:33:03 +00:00
parent 80e430f295
commit 94bec76385
5 changed files with 142 additions and 13 deletions

View File

@ -106,10 +106,10 @@ public final class FunctionEval {
retval[38] = BooleanFunction.NOT;
retval[39] = NumericFunction.MOD;
// 40: DCOUNT
// 41: DSUM
retval[41] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DSUM);
// 42: DAVERAGE
retval[43] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DMIN);
// 44: DMAX
retval[44] = new DStarRunner(DStarRunner.DStarAlgorithmEnum.DMAX);
// 45: DSTDEV
retval[46] = AggregateFunction.VAR;
// 47: DVAR
@ -144,7 +144,6 @@ public final class FunctionEval {
retval[FunctionID.OFFSET] = new Offset(); //nominally 78
retval[82] = TextFunction.SEARCH;
// 83: TRANSPOSE
retval[83] = MatrixFunction.TRANSPOSE;
// 86: TYPE

View File

@ -0,0 +1,60 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.formula.functions;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.NumericValueEval;
import org.apache.poi.ss.formula.eval.ValueEval;
/**
* Implementation of the DMax function:
* Finds the maximum value of a column in an area with given conditions.
*
* TODO:
* - wildcards ? and * in string conditions
* - functions as conditions
*/
public final class DMax implements IDStarAlgorithm {
private ValueEval maximumValue;
@Override
public boolean processMatch(ValueEval eval) {
if(eval instanceof NumericValueEval) {
if(maximumValue == null) { // First match, just set the value.
maximumValue = eval;
} else { // There was a previous match, find the new minimum.
double currentValue = ((NumericValueEval)eval).getNumberValue();
double oldValue = ((NumericValueEval)maximumValue).getNumberValue();
if(currentValue > oldValue) {
maximumValue = eval;
}
}
}
return true;
}
@Override
public ValueEval getResult() {
if(maximumValue == null) {
return NumberEval.ZERO;
} else {
return maximumValue;
}
}
}

View File

@ -17,6 +17,8 @@
package org.apache.poi.ss.formula.functions;
import java.util.function.Supplier;
import org.apache.poi.ss.formula.eval.AreaEval;
import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
@ -39,13 +41,38 @@ import org.apache.poi.ss.util.NumberComparer;
* - functions as conditions
*/
public final class DStarRunner implements Function3Arg {
/**
* Enum for convenience to identify and source implementations of the D* functions
*/
public enum DStarAlgorithmEnum {
DGET,
DMIN,
// DMAX, // DMAX is not yet implemented
/** @see DGet */
DGET(DGet::new),
/** @see DMin */
DMIN(DMin::new),
/** @see DMax */
DMAX(DMax::new),
/** @see DSum */
DSUM(DSum::new),
;
private final Supplier<IDStarAlgorithm> implSupplier;
private DStarAlgorithmEnum(Supplier<IDStarAlgorithm> implSupplier) {
this.implSupplier = implSupplier;
}
/**
* @return a new function implementation instance
*/
public IDStarAlgorithm newInstance() {
return implSupplier.get();
}
}
private final DStarAlgorithmEnum algoType;
/**
* @param algorithm to implement
*/
public DStarRunner(DStarAlgorithmEnum algorithm) {
this.algoType = algorithm;
}
@ -86,13 +113,7 @@ public final class DStarRunner implements Function3Arg {
}
// Create an algorithm runner.
IDStarAlgorithm algorithm;
switch(algoType) {
case DGET: algorithm = new DGet(); break;
case DMIN: algorithm = new DMin(); break;
default:
throw new IllegalStateException("Unexpected algorithm type " + algoType + " encountered.");
}
IDStarAlgorithm algorithm = algoType.newInstance();
// Iterate over all DB entries.
final int height = db.getHeight();

View File

@ -0,0 +1,49 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.formula.functions;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.NumericValueEval;
import org.apache.poi.ss.formula.eval.ValueEval;
/**
* Implementation of the DSum function:
* Finds the total value of matching values in a column in an area with given conditions.
*
* TODO:
* - wildcards ? and * in string conditions
* - functions as conditions
*/
public final class DSum implements IDStarAlgorithm {
private double totalValue = 0;
@Override
public boolean processMatch(ValueEval eval) {
if(eval instanceof NumericValueEval) {
double currentValue = ((NumericValueEval)eval).getNumberValue();
totalValue += currentValue;
}
return true;
}
@Override
public ValueEval getResult() {
return new NumberEval(totalValue);
}
}

Binary file not shown.