3
3
namespace PhpOffice \PhpSpreadsheet \Calculation ;
4
4
5
5
use PhpOffice \PhpSpreadsheet \Calculation \Engine \ArrayArgumentHelper ;
6
+ use PhpOffice \PhpSpreadsheet \Calculation \Engine \ArrayArgumentProcessor ;
6
7
7
8
trait ArrayEnabled
8
9
{
@@ -37,7 +38,7 @@ protected static function evaluateArrayArguments(callable $method, ...$arguments
37
38
self ::initialiseHelper ($ arguments );
38
39
$ arguments = self ::$ arrayArgumentHelper ->arguments ();
39
40
40
- return self ::processArguments ($ method , ...$ arguments );
41
+ return ArrayArgumentProcessor ::processArguments (self :: $ arrayArgumentHelper , $ method , ...$ arguments );
41
42
}
42
43
43
44
/**
@@ -50,162 +51,6 @@ protected static function evaluateArrayArgumentsSubset(callable $method, int $li
50
51
$ arguments = self ::$ arrayArgumentHelper ->arguments ();
51
52
$ arguments = array_merge ($ arguments , $ trailingArguments );
52
53
53
- return self ::processArguments ($ method , ...$ arguments );
54
- }
55
-
56
- /**
57
- * @param mixed ...$arguments
58
- */
59
- private static function processArguments (callable $ method , ...$ arguments ): array
60
- {
61
- if (self ::$ arrayArgumentHelper ->hasArrayArgument () === false ) {
62
- return [$ method (...$ arguments )];
63
- }
64
-
65
- if (self ::$ arrayArgumentHelper ->arrayArguments () === 1 ) {
66
- $ nthArgument = self ::$ arrayArgumentHelper ->getFirstArrayArgumentNumber ();
67
-
68
- return self ::evaluateNthArgumentAsArray ($ method , $ nthArgument , ...$ arguments );
69
- }
70
-
71
- $ singleRowVectorIndex = self ::$ arrayArgumentHelper ->getSingleRowVector ();
72
- $ singleColumnVectorIndex = self ::$ arrayArgumentHelper ->getSingleColumnVector ();
73
- if ($ singleRowVectorIndex !== null && $ singleColumnVectorIndex !== null ) {
74
- // Basic logic for a single row vector and a single column vector
75
- return self ::evaluateVectorPair ($ method , $ singleRowVectorIndex , $ singleColumnVectorIndex , ...$ arguments );
76
- }
77
-
78
- $ matrixPair = self ::$ arrayArgumentHelper ->getMatrixPair ();
79
- if ($ matrixPair !== []) {
80
- if (
81
- (self ::$ arrayArgumentHelper ->isVector ($ matrixPair [0 ]) === true &&
82
- self ::$ arrayArgumentHelper ->isVector ($ matrixPair [1 ]) === false ) ||
83
- (self ::$ arrayArgumentHelper ->isVector ($ matrixPair [0 ]) === false &&
84
- self ::$ arrayArgumentHelper ->isVector ($ matrixPair [1 ]) === true )
85
- ) {
86
- // Logic for a matrix and a vector (row or column)
87
- return self ::evaluateVectorMatrixPair ($ method , $ matrixPair , ...$ arguments );
88
- }
89
- // Logic for matrix/matrix, column vector/column vector or row vector/row vector
90
- return self ::evaluateMatrixPair ($ method , $ matrixPair , ...$ arguments );
91
- }
92
-
93
- // Still need to work out the logic for more than two array arguments,
94
- // For the moment, we're throwing an Exception when we initialise the ArrayArgumentHelper
95
- return ['#VALUE! ' ];
96
- }
97
-
98
- /**
99
- * @param mixed ...$arguments
100
- */
101
- private static function evaluateVectorMatrixPair (callable $ method , array $ matrixIndexes , ...$ arguments ): array
102
- {
103
- $ matrix2 = array_pop ($ matrixIndexes );
104
- /** @var array $matrixValues2 */
105
- $ matrixValues2 = $ arguments [$ matrix2 ];
106
- $ matrix1 = array_pop ($ matrixIndexes );
107
- /** @var array $matrixValues1 */
108
- $ matrixValues1 = $ arguments [$ matrix1 ];
109
-
110
- $ rows = min (array_map ([self ::$ arrayArgumentHelper , 'rowCount ' ], [$ matrix1 , $ matrix2 ]));
111
- $ columns = min (array_map ([self ::$ arrayArgumentHelper , 'columnCount ' ], [$ matrix1 , $ matrix2 ]));
112
-
113
- if ($ rows === 1 ) {
114
- $ rows = max (array_map ([self ::$ arrayArgumentHelper , 'rowCount ' ], [$ matrix1 , $ matrix2 ]));
115
- }
116
- if ($ columns === 1 ) {
117
- $ columns = max (array_map ([self ::$ arrayArgumentHelper , 'columnCount ' ], [$ matrix1 , $ matrix2 ]));
118
- }
119
-
120
- $ result = [];
121
- for ($ rowIndex = 0 ; $ rowIndex < $ rows ; ++$ rowIndex ) {
122
- for ($ columnIndex = 0 ; $ columnIndex < $ columns ; ++$ columnIndex ) {
123
- $ rowIndex1 = self ::$ arrayArgumentHelper ->isRowVector ($ matrix1 ) ? 0 : $ rowIndex ;
124
- $ columnIndex1 = self ::$ arrayArgumentHelper ->isColumnVector ($ matrix1 ) ? 0 : $ columnIndex ;
125
- $ value1 = $ matrixValues1 [$ rowIndex1 ][$ columnIndex1 ];
126
- $ rowIndex2 = self ::$ arrayArgumentHelper ->isRowVector ($ matrix2 ) ? 0 : $ rowIndex ;
127
- $ columnIndex2 = self ::$ arrayArgumentHelper ->isColumnVector ($ matrix2 ) ? 0 : $ columnIndex ;
128
- $ value2 = $ matrixValues2 [$ rowIndex2 ][$ columnIndex2 ];
129
- $ arguments [$ matrix1 ] = $ value1 ;
130
- $ arguments [$ matrix2 ] = $ value2 ;
131
-
132
- $ result [$ rowIndex ][$ columnIndex ] = $ method (...$ arguments );
133
- }
134
- }
135
-
136
- return $ result ;
137
- }
138
-
139
- /**
140
- * @param mixed ...$arguments
141
- */
142
- private static function evaluateMatrixPair (callable $ method , array $ matrixIndexes , ...$ arguments ): array
143
- {
144
- $ matrix2 = array_pop ($ matrixIndexes );
145
- /** @var array $matrixValues2 */
146
- $ matrixValues2 = $ arguments [$ matrix2 ];
147
- $ matrix1 = array_pop ($ matrixIndexes );
148
- /** @var array $matrixValues1 */
149
- $ matrixValues1 = $ arguments [$ matrix1 ];
150
-
151
- $ result = [];
152
- foreach ($ matrixValues1 as $ rowIndex => $ row ) {
153
- foreach ($ row as $ columnIndex => $ value1 ) {
154
- if (isset ($ matrixValues2 [$ rowIndex ][$ columnIndex ]) === false ) {
155
- continue ;
156
- }
157
-
158
- $ value2 = $ matrixValues2 [$ rowIndex ][$ columnIndex ];
159
- $ arguments [$ matrix1 ] = $ value1 ;
160
- $ arguments [$ matrix2 ] = $ value2 ;
161
-
162
- $ result [$ rowIndex ][$ columnIndex ] = $ method (...$ arguments );
163
- }
164
- }
165
-
166
- return $ result ;
167
- }
168
-
169
- /**
170
- * @param mixed ...$arguments
171
- */
172
- private static function evaluateVectorPair (callable $ method , int $ rowIndex , int $ columnIndex , ...$ arguments ): array
173
- {
174
- $ rowVector = Functions::flattenArray ($ arguments [$ rowIndex ]);
175
- $ columnVector = Functions::flattenArray ($ arguments [$ columnIndex ]);
176
-
177
- $ result = [];
178
- foreach ($ columnVector as $ column ) {
179
- $ rowResults = [];
180
- foreach ($ rowVector as $ row ) {
181
- $ arguments [$ rowIndex ] = $ row ;
182
- $ arguments [$ columnIndex ] = $ column ;
183
-
184
- $ rowResults [] = $ method (...$ arguments );
185
- }
186
- $ result [] = $ rowResults ;
187
- }
188
-
189
- return $ result ;
190
- }
191
-
192
- /**
193
- * Note, offset is from 1 (for the first argument) rather than from 0.
194
- *
195
- * @param mixed ...$arguments
196
- */
197
- private static function evaluateNthArgumentAsArray (callable $ method , int $ nthArgument , ...$ arguments ): array
198
- {
199
- $ values = array_slice ($ arguments , $ nthArgument - 1 , 1 );
200
- /** @var array $values */
201
- $ values = array_pop ($ values );
202
-
203
- $ result = [];
204
- foreach ($ values as $ value ) {
205
- $ arguments [$ nthArgument - 1 ] = $ value ;
206
- $ result [] = $ method (...$ arguments );
207
- }
208
-
209
- return $ result ;
54
+ return ArrayArgumentProcessor::processArguments (self ::$ arrayArgumentHelper , $ method , ...$ arguments );
210
55
}
211
56
}
0 commit comments