/*
|
* 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.
|
*/
|
|
namespace HH.WMS.Utils.NPOI.SS.Formula.Functions
|
{
|
using System;
|
using System.Collections;
|
using HH.WMS.Utils.NPOI.Util;
|
using HH.WMS.Utils.NPOI.SS.Formula.Eval;
|
using HH.WMS.Utils.NPOI.SS.Formula;
|
/**
|
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
|
*
|
*/
|
public class Mode : Function
|
{
|
/**
|
* if v is zero length or contains no duplicates, return value is
|
* Double.NaN. Else returns the value that occurs most times and if there is
|
* a tie, returns the first such value.
|
*
|
* @param v
|
*/
|
public static double Evaluate(double[] v)
|
{
|
if (v.Length < 2)
|
{
|
throw new EvaluationException(ErrorEval.NA);
|
}
|
|
// very naive impl, may need to be optimized
|
int[] counts = new int[v.Length];
|
Arrays.Fill(counts, 1);
|
for (int i = 0, iSize = v.Length; i < iSize; i++)
|
{
|
for (int j = i + 1, jSize = v.Length; j < jSize; j++)
|
{
|
if (v[i] == v[j])
|
counts[i]++;
|
}
|
}
|
double maxv = 0;
|
int maxc = 0;
|
for (int i = 0, iSize = counts.Length; i < iSize; i++)
|
{
|
if (counts[i] > maxc)
|
{
|
maxv = v[i];
|
maxc = counts[i];
|
}
|
}
|
if (maxc > 1)
|
{
|
return maxv;
|
}
|
throw new EvaluationException(ErrorEval.NA);
|
|
}
|
|
public ValueEval Evaluate(ValueEval[] args, int srcCellRow, int srcCellCol)
|
{
|
double result;
|
try
|
{
|
IList temp = new ArrayList();
|
for (int i = 0; i < args.Length; i++)
|
{
|
CollectValues(args[i], temp);
|
}
|
double[] values = new double[temp.Count];
|
for (int i = 0; i < values.Length; i++)
|
{
|
values[i] = (Double)temp[i];
|
}
|
result = Evaluate(values);
|
}
|
catch (EvaluationException e)
|
{
|
return e.GetErrorEval();
|
}
|
return new NumberEval(result);
|
}
|
|
private static void CollectValues(ValueEval arg, IList temp)
|
{
|
if (arg is TwoDEval)
|
{
|
TwoDEval ae = (TwoDEval)arg;
|
int width = ae.Width;
|
int height = ae.Height;
|
for (int rrIx = 0; rrIx < height; rrIx++)
|
{
|
for (int rcIx = 0; rcIx < width; rcIx++)
|
{
|
ValueEval ve1 = ae.GetValue(rrIx, rcIx);
|
CollectValue(ve1, temp, false);
|
}
|
}
|
return;
|
}
|
if (arg is RefEval)
|
{
|
RefEval re = (RefEval)arg;
|
CollectValue(re.InnerValueEval, temp, true);
|
return;
|
}
|
CollectValue(arg, temp, true);
|
|
}
|
|
private static void CollectValue(ValueEval arg, IList temp, bool mustBeNumber)
|
{
|
if (arg is ErrorEval)
|
{
|
throw new EvaluationException((ErrorEval)arg);
|
}
|
if (arg == BlankEval.instance || arg is BoolEval || arg is StringEval)
|
{
|
if (mustBeNumber)
|
{
|
throw EvaluationException.InvalidValue();
|
}
|
return;
|
}
|
if (arg is NumberEval)
|
{
|
temp.Add(((NumberEval)arg).NumberValue);
|
return;
|
}
|
throw new InvalidOperationException("Unexpected value type (" + arg.GetType().Name + ")");
|
}
|
}
|
}
|