Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace PhpOffice\PhpSpreadsheet\Calculation\Engine;
4
 
5
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
6
 
7
class ArrayArgumentHelper
8
{
9
    protected int $indexStart = 0;
10
 
11
    protected array $arguments;
12
 
13
    protected int $argumentCount;
14
 
15
    protected array $rows;
16
 
17
    protected array $columns;
18
 
19
    public function initialise(array $arguments): void
20
    {
21
        $keys = array_keys($arguments);
22
        $this->indexStart = (int) array_shift($keys);
23
        $this->rows = $this->rows($arguments);
24
        $this->columns = $this->columns($arguments);
25
 
26
        $this->argumentCount = count($arguments);
27
        $this->arguments = $this->flattenSingleCellArrays($arguments, $this->rows, $this->columns);
28
 
29
        $this->rows = $this->rows($arguments);
30
        $this->columns = $this->columns($arguments);
31
 
32
        if ($this->arrayArguments() > 2) {
33
            throw new Exception('Formulae with more than two array arguments are not supported');
34
        }
35
    }
36
 
37
    public function arguments(): array
38
    {
39
        return $this->arguments;
40
    }
41
 
42
    public function hasArrayArgument(): bool
43
    {
44
        return $this->arrayArguments() > 0;
45
    }
46
 
47
    public function getFirstArrayArgumentNumber(): int
48
    {
49
        $rowArrays = $this->filterArray($this->rows);
50
        $columnArrays = $this->filterArray($this->columns);
51
 
52
        for ($index = $this->indexStart; $index < $this->argumentCount; ++$index) {
53
            if (isset($rowArrays[$index]) || isset($columnArrays[$index])) {
54
                return ++$index;
55
            }
56
        }
57
 
58
        return 0;
59
    }
60
 
61
    public function getSingleRowVector(): ?int
62
    {
63
        $rowVectors = $this->getRowVectors();
64
 
65
        return count($rowVectors) === 1 ? array_pop($rowVectors) : null;
66
    }
67
 
68
    private function getRowVectors(): array
69
    {
70
        $rowVectors = [];
71
        for ($index = $this->indexStart; $index < ($this->indexStart + $this->argumentCount); ++$index) {
72
            if ($this->rows[$index] === 1 && $this->columns[$index] > 1) {
73
                $rowVectors[] = $index;
74
            }
75
        }
76
 
77
        return $rowVectors;
78
    }
79
 
80
    public function getSingleColumnVector(): ?int
81
    {
82
        $columnVectors = $this->getColumnVectors();
83
 
84
        return count($columnVectors) === 1 ? array_pop($columnVectors) : null;
85
    }
86
 
87
    private function getColumnVectors(): array
88
    {
89
        $columnVectors = [];
90
        for ($index = $this->indexStart; $index < ($this->indexStart + $this->argumentCount); ++$index) {
91
            if ($this->rows[$index] > 1 && $this->columns[$index] === 1) {
92
                $columnVectors[] = $index;
93
            }
94
        }
95
 
96
        return $columnVectors;
97
    }
98
 
99
    public function getMatrixPair(): array
100
    {
101
        for ($i = $this->indexStart; $i < ($this->indexStart + $this->argumentCount - 1); ++$i) {
102
            for ($j = $i + 1; $j < $this->argumentCount; ++$j) {
103
                if (isset($this->rows[$i], $this->rows[$j])) {
104
                    return [$i, $j];
105
                }
106
            }
107
        }
108
 
109
        return [];
110
    }
111
 
112
    public function isVector(int $argument): bool
113
    {
114
        return $this->rows[$argument] === 1 || $this->columns[$argument] === 1;
115
    }
116
 
117
    public function isRowVector(int $argument): bool
118
    {
119
        return $this->rows[$argument] === 1;
120
    }
121
 
122
    public function isColumnVector(int $argument): bool
123
    {
124
        return $this->columns[$argument] === 1;
125
    }
126
 
127
    public function rowCount(int $argument): int
128
    {
129
        return $this->rows[$argument];
130
    }
131
 
132
    public function columnCount(int $argument): int
133
    {
134
        return $this->columns[$argument];
135
    }
136
 
137
    private function rows(array $arguments): array
138
    {
139
        return array_map(
140
            fn ($argument): int => is_countable($argument) ? count($argument) : 1,
141
            $arguments
142
        );
143
    }
144
 
145
    private function columns(array $arguments): array
146
    {
147
        return array_map(
148
            fn (mixed $argument): int => is_array($argument) && is_array($argument[array_keys($argument)[0]])
149
                    ? count($argument[array_keys($argument)[0]])
150
                    : 1,
151
            $arguments
152
        );
153
    }
154
 
155
    public function arrayArguments(): int
156
    {
157
        $count = 0;
158
        foreach (array_keys($this->arguments) as $argument) {
159
            if ($this->rows[$argument] > 1 || $this->columns[$argument] > 1) {
160
                ++$count;
161
            }
162
        }
163
 
164
        return $count;
165
    }
166
 
167
    private function flattenSingleCellArrays(array $arguments, array $rows, array $columns): array
168
    {
169
        foreach ($arguments as $index => $argument) {
170
            if ($rows[$index] === 1 && $columns[$index] === 1) {
171
                while (is_array($argument)) {
172
                    $argument = array_pop($argument);
173
                }
174
                $arguments[$index] = $argument;
175
            }
176
        }
177
 
178
        return $arguments;
179
    }
180
 
181
    private function filterArray(array $array): array
182
    {
183
        return array_filter(
184
            $array,
185
            fn ($value): bool => $value > 1
186
        );
187
    }
188
}