Passed
Push — master ( a950d1...8a122f )
by Mark
14:29
created

Matrix::extractRowValue()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
cc 3
eloc 7
c 0
b 0
f 0
nc 3
nop 3
dl 0
loc 13
ccs 7
cts 8
cp 0.875
crap 3.0175
rs 10
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\LookupRef;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
8
9
class Matrix
10
{
11
    use ArrayEnabled;
12
13
    /**
14
     * Helper function; NOT an implementation of any Excel Function.
15
     */
16 6
    public static function isColumnVector(array $values): bool
17
    {
18 6
        return count($values, COUNT_RECURSIVE) === (count($values, COUNT_NORMAL) * 2);
19
    }
20
21
    /**
22
     * Helper function; NOT an implementation of any Excel Function.
23
     */
24 4
    public static function isRowVector(array $values): bool
25
    {
26 4
        return count($values, COUNT_RECURSIVE) > 1 &&
27 4
            (count($values, COUNT_NORMAL) === 1 || count($values, COUNT_RECURSIVE) === count($values, COUNT_NORMAL));
28
    }
29
30
    /**
31
     * TRANSPOSE.
32
     *
33
     * @param array|mixed $matrixData A matrix of values
34
     *
35
     * @return array
36
     */
37 22
    public static function transpose($matrixData)
38
    {
39 22
        $returnMatrix = [];
40 22
        if (!is_array($matrixData)) {
41 1
            $matrixData = [[$matrixData]];
42
        }
43
44 22
        $column = 0;
45 22
        foreach ($matrixData as $matrixRow) {
46 22
            $row = 0;
47 22
            foreach ($matrixRow as $matrixCell) {
48 22
                $returnMatrix[$row][$column] = $matrixCell;
49 22
                ++$row;
50
            }
51 22
            ++$column;
52
        }
53
54 22
        return $returnMatrix;
55
    }
56
57
    /**
58
     * INDEX.
59
     *
60
     * Uses an index to choose a value from a reference or array
61
     *
62
     * Excel Function:
63
     *        =INDEX(range_array, row_num, [column_num], [area_num])
64
     *
65
     * @param mixed $matrix A range of cells or an array constant
66
     * @param mixed $rowNum The row in the array or range from which to return a value.
67
     *                          If row_num is omitted, column_num is required.
68
     *                      Or can be an array of values
69
     * @param mixed $columnNum The column in the array or range from which to return a value.
70
     *                          If column_num is omitted, row_num is required.
71
     *                      Or can be an array of values
72
     *
73
     * TODO Provide support for area_num, currently not supported
74
     *
75
     * @return mixed the value of a specified cell or array of cells
76
     *         If an array of values is passed as the $rowNum and/or $columnNum arguments, then the returned result
77
     *            will also be an array with the same dimensions
78
     */
79 60
    public static function index($matrix, $rowNum = 0, $columnNum = null)
80
    {
81 60
        if (is_array($rowNum) || is_array($columnNum)) {
82 18
            return self::evaluateArrayArgumentsSubsetFrom([self::class, __FUNCTION__], 1, $matrix, $rowNum, $columnNum);
83
        }
84
85 60
        $rowNum = $rowNum ?? 0;
86 60
        $originalColumnNum = $columnNum;
87 60
        $columnNum = $columnNum ?? 0;
88
89
        try {
90 60
            $rowNum = LookupRefValidations::validatePositiveInt($rowNum);
91 53
            $columnNum = LookupRefValidations::validatePositiveInt($columnNum);
92 14
        } catch (Exception $e) {
93 14
            return $e->getMessage();
94
        }
95
96 46
        if (!is_array($matrix) || ($rowNum > count($matrix))) {
97 2
            return ExcelError::REF();
98
        }
99
100 44
        $rowKeys = array_keys($matrix);
101 44
        $columnKeys = @array_keys($matrix[$rowKeys[0]]);
102
103 44
        if ($columnNum > count($columnKeys)) {
104 2
            return ExcelError::REF();
105
        }
106 42
        if ($originalColumnNum === null && 1 < count($columnKeys)) {
107 1
            return ExcelError::REF();
108
        }
109
110 41
        if ($columnNum === 0) {
111 27
            return self::extractRowValue($matrix, $rowKeys, $rowNum);
112
        }
113
114 15
        $columnNum = $columnKeys[--$columnNum];
115 15
        if ($rowNum === 0) {
116 4
            return array_map(
117 4
                function ($value) {
118 4
                    return [$value];
119 4
                },
120 4
                array_column($matrix, $columnNum)
121 4
            );
122
        }
123 12
        $rowNum = $rowKeys[--$rowNum];
124
125 12
        return $matrix[$rowNum][$columnNum];
126
    }
127
128
    /** @return mixed */
129 27
    private static function extractRowValue(array $matrix, array $rowKeys, int $rowNum)
130
    {
131 27
        if ($rowNum === 0) {
132 2
            return $matrix;
133
        }
134
135 25
        $rowNum = $rowKeys[--$rowNum];
136 25
        $row = $matrix[$rowNum];
137 25
        if (is_array($row)) {
138 25
            return [$rowNum => $row];
139
        }
140
141
        return $row;
142
    }
143
}
144