summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-10-28 22:17:33 +0800
committerxuri <xuri.me@gmail.com>2021-10-28 22:17:33 +0800
commitffc998941c12f84917e15b74e6db7a936d5aab76 (patch)
tree5015078996c046ae97d5d3e2eb229a5bea3807e8 /calc.go
parent2e9635ece8ecf2617b0144451029aeca78edd9d9 (diff)
ref #65: new formula functions SWITCH and TRIMMEAN
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/calc.go b/calc.go
index 6f8dcb6..2c05176 100644
--- a/calc.go
+++ b/calc.go
@@ -533,6 +533,7 @@ type formulaFuncs struct {
// SUM
// SUMIF
// SUMSQ
+// SWITCH
// SYD
// T
// TAN
@@ -545,6 +546,7 @@ type formulaFuncs struct {
// TODAY
// TRANSPOSE
// TRIM
+// TRIMMEAN
// TRUE
// TRUNC
// UNICHAR
@@ -5741,6 +5743,49 @@ func (fn *formulaFuncs) SMALL(argsList *list.List) formulaArg {
return fn.kth("SMALL", argsList)
}
+// TRIMMEAN function calculates the trimmed mean (or truncated mean) of a
+// supplied set of values. The syntax of the function is:
+//
+// TRIMMEAN(array,percent)
+//
+func (fn *formulaFuncs) TRIMMEAN(argsList *list.List) formulaArg {
+ if argsList.Len() != 2 {
+ return newErrorFormulaArg(formulaErrorVALUE, "TRIMMEAN requires 2 arguments")
+ }
+ percent := argsList.Back().Value.(formulaArg).ToNumber()
+ if percent.Type != ArgNumber {
+ return percent
+ }
+ if percent.Number < 0 || percent.Number >= 1 {
+ return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
+ }
+ arr := []float64{}
+ arrArg := argsList.Front().Value.(formulaArg).ToList()
+ for _, cell := range arrArg {
+ num := cell.ToNumber()
+ if num.Type != ArgNumber {
+ continue
+ }
+ arr = append(arr, num.Number)
+ }
+ discard := math.Floor(float64(len(arr)) * percent.Number / 2)
+ sort.Float64s(arr)
+ for i := 0; i < int(discard); i++ {
+ if len(arr) > 0 {
+ arr = arr[1:]
+ }
+ if len(arr) > 0 {
+ arr = arr[:len(arr)-1]
+ }
+ }
+
+ args := list.New().Init()
+ for _, ele := range arr {
+ args.PushBack(newNumberFormulaArg(ele))
+ }
+ return fn.AVERAGE(args)
+}
+
// VARP function returns the Variance of a given set of values. The syntax of
// the function is:
//
@@ -6326,6 +6371,41 @@ func (fn *formulaFuncs) OR(argsList *list.List) formulaArg {
return newStringFormulaArg(strings.ToUpper(strconv.FormatBool(or)))
}
+// SWITCH function compares a number of supplied values to a supplied test
+// expression and returns a result corresponding to the first value that
+// matches the test expression. A default value can be supplied, to be
+// returned if none of the supplied values match the test expression. The
+// syntax of the function is:
+//
+//
+// SWITCH(expression,value1,result1,[value2,result2],[value3,result3],...,[default])
+//
+func (fn *formulaFuncs) SWITCH(argsList *list.List) formulaArg {
+ if argsList.Len() < 3 {
+ return newErrorFormulaArg(formulaErrorVALUE, "SWITCH requires at least 3 arguments")
+ }
+ target := argsList.Front().Value.(formulaArg)
+ argCount := argsList.Len() - 1
+ switchCount := int(math.Floor(float64(argCount) / 2))
+ hasDefaultClause := argCount%2 != 0
+ result := newErrorFormulaArg(formulaErrorNA, formulaErrorNA)
+ if hasDefaultClause {
+ result = argsList.Back().Value.(formulaArg)
+ }
+ if switchCount > 0 {
+ arg := argsList.Front()
+ for i := 0; i < switchCount; i++ {
+ arg = arg.Next()
+ if target.Value() == arg.Value.(formulaArg).Value() {
+ result = arg.Next().Value.(formulaArg)
+ break
+ }
+ arg = arg.Next()
+ }
+ }
+ return result
+}
+
// TRUE function returns the logical value TRUE. The syntax of the function
// is:
//