chengkun
2025-09-15 0cc7f61de2b106c9664033fc27d6426d072ea019
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
 
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical;
 
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
 
class Size
{
    /**
     * LARGE.
     *
     * Returns the nth largest value in a data set. You can use this function to
     *        select a value based on its relative standing.
     *
     * Excel Function:
     *        LARGE(value1[,value2[, ...]],entry)
     *
     * @param mixed $args Data values
     *
     * @return float|string The result, or a string containing an error
     */
    public static function large(mixed ...$args)
    {
        $aArgs = Functions::flattenArray($args);
        $entry = array_pop($aArgs);
 
        if ((is_numeric($entry)) && (!is_string($entry))) {
            $entry = (int) floor($entry);
 
            $mArgs = self::filter($aArgs);
            $count = Counts::COUNT($mArgs);
            --$entry;
            if ($count === 0 || $entry < 0 || $entry >= $count) {
                return ExcelError::NAN();
            }
            rsort($mArgs);
 
            return $mArgs[$entry];
        }
 
        return ExcelError::VALUE();
    }
 
    /**
     * SMALL.
     *
     * Returns the nth smallest value in a data set. You can use this function to
     *        select a value based on its relative standing.
     *
     * Excel Function:
     *        SMALL(value1[,value2[, ...]],entry)
     *
     * @param mixed $args Data values
     *
     * @return float|string The result, or a string containing an error
     */
    public static function small(mixed ...$args)
    {
        $aArgs = Functions::flattenArray($args);
 
        $entry = array_pop($aArgs);
 
        if ((is_numeric($entry)) && (!is_string($entry))) {
            $entry = (int) floor($entry);
 
            $mArgs = self::filter($aArgs);
            $count = Counts::COUNT($mArgs);
            --$entry;
            if ($count === 0 || $entry < 0 || $entry >= $count) {
                return ExcelError::NAN();
            }
            sort($mArgs);
 
            return $mArgs[$entry];
        }
 
        return ExcelError::VALUE();
    }
 
    /**
     * @param mixed[] $args Data values
     */
    protected static function filter(array $args): array
    {
        $mArgs = [];
 
        foreach ($args as $arg) {
            // Is it a numeric value?
            if ((is_numeric($arg)) && (!is_string($arg))) {
                $mArgs[] = $arg;
            }
        }
 
        return $mArgs;
    }
}