@@ -14582,21 +14582,19 @@ func (fn *formulaFuncs) UNICODE(argsList *list.List) formulaArg {
1458214582 return fn.code("UNICODE", argsList)
1458314583}
1458414584
14585- // UNIQUE function returns a list of unique values in a list or range.
14586- // For syntax refer to
14587- // https://support.microsoft.com/en-us/office/unique-function-c5ab87fd-30a3-4ce9-9d1a-40204fb85e1e.
14585+ // UNIQUE function returns a list of unique values in a list or range. The
14586+ // syntax of the function is:
14587+ //
14588+ // UNIQUE(array,[by_col],[exactly_once])
1458814589func (fn *formulaFuncs) UNIQUE(argsList *list.List) formulaArg {
1458914590 args, errArg := getFormulaUniqueArgs(argsList)
1459014591 if errArg != nil {
1459114592 return *errArg
1459214593 }
14593-
1459414594 if args.byColumn {
1459514595 args.cellRange, args.cols, args.rows = transposeFormulaArgsList(args.cellRange, args.cols, args.rows)
1459614596 }
14597-
1459814597 counts := map[string]int{}
14599-
1460014598 for i := 0; i < len(args.cellRange); i += args.cols {
1460114599 key := concatValues(args.cellRange[i : i+args.cols])
1460214600
@@ -14605,9 +14603,7 @@ func (fn *formulaFuncs) UNIQUE(argsList *list.List) formulaArg {
1460514603 }
1460614604 counts[key]++
1460714605 }
14608-
1460914606 uniqueAxes := [][]formulaArg{}
14610-
1461114607 for i := 0; i < len(args.cellRange); i += args.cols {
1461214608 key := concatValues(args.cellRange[i : i+args.cols])
1461314609
@@ -14616,37 +14612,33 @@ func (fn *formulaFuncs) UNIQUE(argsList *list.List) formulaArg {
1461614612 }
1461714613 delete(counts, key)
1461814614 }
14619-
1462014615 if args.byColumn {
1462114616 uniqueAxes = transposeFormulaArgsMatrix(uniqueAxes)
1462214617 }
14623-
1462414618 return newMatrixFormulaArg(uniqueAxes)
1462514619}
1462614620
14621+ // transposeFormulaArgsMatrix transposes a 2D slice of formulaArg.
1462714622func transposeFormulaArgsMatrix(args [][]formulaArg) [][]formulaArg {
1462814623 if len(args) == 0 {
1462914624 return args
1463014625 }
14631-
1463214626 transposedArgs := make([][]formulaArg, len(args[0]))
14633-
1463414627 for i := 0; i < len(args[0]); i++ {
1463514628 transposedArgs[i] = make([]formulaArg, len(args))
1463614629 }
14637-
1463814630 for i := 0; i < len(args); i++ {
1463914631 for j := 0; j < len(args[i]); j++ {
1464014632 transposedArgs[j][i] = args[i][j]
1464114633 }
1464214634 }
14643-
1464414635 return transposedArgs
1464514636}
1464614637
14638+ // transposeFormulaArgsList transposes a flat slice of formulaArg given the
14639+ // number of columns and rows.
1464714640func transposeFormulaArgsList(args []formulaArg, cols, rows int) ([]formulaArg, int, int) {
1464814641 transposedArgs := make([]formulaArg, len(args))
14649-
1465014642 for i := 0; i < rows; i++ {
1465114643 for j := 0; j < cols; j++ {
1465214644 transposedArgs[j*rows+i] = args[i*cols+j]
@@ -14655,6 +14647,8 @@ func transposeFormulaArgsList(args []formulaArg, cols, rows int) ([]formulaArg,
1465514647 return transposedArgs, rows, cols
1465614648}
1465714649
14650+ // concatValues concatenates the values of a slice of formulaArg into a single
14651+ // string.
1465814652func concatValues(args []formulaArg) string {
1465914653 val := ""
1466014654 for _, arg := range args {
@@ -14664,6 +14658,7 @@ func concatValues(args []formulaArg) string {
1466414658 return val
1466514659}
1466614660
14661+ // uniqueArgs holds the parsed arguments for the UNIQUE function.
1466714662type uniqueArgs struct {
1466814663 cellRange []formulaArg
1466914664 cols int
@@ -14672,22 +14667,21 @@ type uniqueArgs struct {
1467214667 exactlyOnce bool
1467314668}
1467414669
14670+ // getFormulaUniqueArgs parses and validates the arguments for the UNIQUE
14671+ // function.
1467514672func getFormulaUniqueArgs(argsList *list.List) (uniqueArgs, *formulaArg) {
1467614673 res := uniqueArgs{}
14677-
1467814674 argsLen := argsList.Len()
1467914675 if argsLen == 0 {
1468014676 errArg := newErrorFormulaArg(formulaErrorVALUE, "UNIQUE requires at least 1 argument")
1468114677 return res, &errArg
1468214678 }
14683-
1468414679 if argsLen > 3 {
1468514680 msg := fmt.Sprintf("UNIQUE takes at most 3 arguments, received %d arguments", argsLen)
1468614681 errArg := newErrorFormulaArg(formulaErrorVALUE, msg)
1468714682
1468814683 return res, &errArg
1468914684 }
14690-
1469114685 firstArg := argsList.Front()
1469214686 res.cellRange = firstArg.Value.(formulaArg).ToList()
1469314687 if len(res.cellRange) == 0 {
@@ -14697,33 +14691,27 @@ func getFormulaUniqueArgs(argsList *list.List) (uniqueArgs, *formulaArg) {
1469714691 if res.cellRange[0].Type == ArgError {
1469814692 return res, &res.cellRange[0]
1469914693 }
14700-
1470114694 rmin, rmax := calcColsRowsMinMax(false, argsList)
1470214695 cmin, cmax := calcColsRowsMinMax(true, argsList)
1470314696 res.cols, res.rows = cmax-cmin+1, rmax-rmin+1
14704-
1470514697 secondArg := firstArg.Next()
1470614698 if secondArg == nil {
1470714699 return res, nil
1470814700 }
14709-
1471014701 argByColumn := secondArg.Value.(formulaArg).ToBool()
1471114702 if argByColumn.Type == ArgError {
1471214703 return res, &argByColumn
1471314704 }
1471414705 res.byColumn = (argByColumn.Value() == "TRUE")
14715-
1471614706 thirdArg := secondArg.Next()
1471714707 if thirdArg == nil {
1471814708 return res, nil
1471914709 }
14720-
1472114710 argExactlyOnce := thirdArg.Value.(formulaArg).ToBool()
1472214711 if argExactlyOnce.Type == ArgError {
1472314712 return res, &argExactlyOnce
1472414713 }
1472514714 res.exactlyOnce = (argExactlyOnce.Value() == "TRUE")
14726-
1472714715 return res, nil
1472814716}
1472914717
0 commit comments