Skip to content

Commit

Permalink
KOGITO-8447:[Dashbuilder]Support MEDIAN aggregation function (apache#…
Browse files Browse the repository at this point in the history
…1406)

* KOGITO-8447:[Dashbuilder]Support MEDIAN aggregation function

* Fixing copyright header
  • Loading branch information
jesuino authored Jan 11, 2023
1 parent 6f9d73e commit 7685619
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ public enum AggregateFunctionType {
AVERAGE,
SUM,
MIN,
MAX;
MAX,
MEDIAN;

private static AggregateFunctionType[] _typeArray = values();
private static List<AggregateFunctionType> _numericOnly = Arrays.asList(AVERAGE, SUM, MAX, MIN);
private static List<AggregateFunctionType> _numericOnly = Arrays.asList(AVERAGE, MEDIAN, SUM, MAX, MIN);

public int getIndex() {
for (int i = 0; i < _typeArray.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public AggregateFunctionManagerImpl() {
registerFunction(new DistinctFunction());
registerFunction(new SumFunction());
registerFunction(new AverageFunction());
registerFunction(new MedianFunction());
registerFunction(new MaxFunction());
registerFunction(new MinFunction());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright 2023 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.dashbuilder.dataset.engine.function;

import java.util.List;
import java.util.stream.Collectors;

import org.dashbuilder.dataset.group.AggregateFunctionType;

/**
* It calculates the average value of a set of numbers.
*/
public class MedianFunction extends AbstractFunction {

public MedianFunction() {
super();
}

public AggregateFunctionType getType() {
return AggregateFunctionType.MEDIAN;
}

public Object aggregate(List values) {
if (values == null || values.isEmpty()) {
return 0d;
}

var n = values.size();

if (n == 1) {
return ((Number) values.get(0)).doubleValue();
}

var sortedValues = values.stream().mapToDouble(v -> ((Number) v).doubleValue()).sorted().toArray();

if (n % 2 == 1) {
return sortedValues[n / 2];
}
var middle = n / 2;
var ii = n == 2 ? 0 : middle - 1;
var is = n == 2 ? 1 : middle + 1;
var v = (sortedValues[ii] + sortedValues[is]) / 2d;
return round(v, precission);
}

public Object aggregate(List values, List<Integer> rows) {
if (rows == null) {
return aggregate(values);
}
if (rows.isEmpty()) {
return 0d;
}
if (values == null || values.isEmpty()) {
return 0d;
}
var _values = rows.stream()
.map(values::get)
.collect(Collectors.toList());
return this.aggregate(_values);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,20 @@ public void testAvgFunctionEmpty() {
Object result = function.aggregate(EMPTY_LIST);
assertEquals(result, 0d);
}

@Test
public void testMedianFunction() {
var function = new MedianFunction();
var values = List.of(1, 2, 3);
var result = function.aggregate(values);
assertEquals(result, 2d);

values = List.of(1, 4);
result = function.aggregate(values);
assertEquals(result, 2.5d);

values = List.of(1);
result = function.aggregate(values);
assertEquals(result, 1.0d);
}
}

0 comments on commit 7685619

Please sign in to comment.