Functional::reduce()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php namespace Mbh\Collection\Traits;
2
3
use Mbh\Collection\Interfaces\Collection as CollectionInterface;
4
use Mbh\Collection\FixedArray;
5
use Mbh\Collection\CallbackHeap;
6
use Mbh\Iterator\SliceIterator;
7
use Mbh\Iterator\ConcatIterator;
8
use SplFixedArray;
9
use SplHeap;
10
use SplStack;
11
use LimitIterator;
12
use Iterator;
13
use ArrayAccess;
14
use Countable;
15
use CallbackFilterIterator;
16
use JsonSerializable;
17
use RuntimeException;
18
use Traversable;
19
use ReflectionClass;
20
use UnderflowException;
21
use OutOfRangeException;
22
23
/**
24
 * MBHFramework
25
 *
26
 * @link      https://github.com/MBHFramework/mbh-framework
27
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
28
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
29
 */
30
31
trait Functional
32
{
33
    use Functional\InPlaceSort {
34
        Functional\InPlaceSort::heapSort as heapSortWithCallback;
35
    }
36
37
    protected function getSplFixedArrayAndSize()
38
    {
39
        $count = $this->count();
40
        return [new SplFixedArray($count), $count];
41
    }
42
43
    /**
44
     * @inheritDoc
45
     */
46
    public function any(callable $callback)
47
    {
48
        $count = $this->count();
49
50
        for ($i = 0; $i < $count; $i++) {
51
            $this[$i] = $callback($this[$i], $i, $this);
52
        }
53
54
        return $this;
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60
    public function concat(...$args)
61
    {
62
        array_unshift($args, $this);
63
64
        // Concat this iterator, and variadic args
65
        $class = new ReflectionClass('Mbh\Iterator\ConcatIterator');
66
        $concatIt = $class->newInstanceArgs($args);
67
68
        // Create as new immutable's iterator
69
        return static::fromArray($concatIt->toArray());
70
    }
71
72
    /**
73
     * @inheritDoc
74
     */
75
    public function find(callable $callback)
76
    {
77
        foreach ($this as $i => $elem) {
78
            if ($callback($elem, $i, $this)) {
79
                return $elem;
80
            }
81
        }
82
    }
83
84
    /**
85
     * @inheritDoc
86
     */
87
    public function filter(callable $callback)
88
    {
89
        list($sfa, $count) = $this->getSplFixedArrayAndSize();
90
91
        $newCount = 0;
92
        foreach ($this as $elem) {
93
            if ($callback($elem)) {
94
                $sfa[$newCount++] = $elem;
95
            }
96
        }
97
98
        $sfa->setSize($newCount);
99
        return static::fromItems($sfa);
100
    }
101
102
    /**
103
     * @inheritDoc
104
     */
105
    public function heapSort(SplHeap $heap)
106
    {
107
        foreach ($this as $item) {
108
            $heap->insert($item);
109
        }
110
111
        $this->setValues(static::fromItems($heap));
112
113
        return $this;
114
    }
115
116
    /**
117
     * @inheritDoc
118
     */
119
    public function join(string $token = ',', string $secondToken = null): string
120
    {
121
        $str = "";
122
        if ($secondToken !== null) {
123
            foreach ($this as $i => $elem) {
124
                $str .= $token . (string) $elem . $secondToken;
125
            }
126
        } else {
127
            $this->rewind();
128
            while ($this->valid()) {
129
                $str .= (string) $this->current();
130
                $this->next();
131
                if ($this->valid()) {
132
                    $str .= $token;
133
                }
134
            }
135
        }
136
137
        return $str;
138
    }
139
140
    /**
141
     * @inheritDoc
142
     */
143
    public function map(callable $callback)
144
    {
145
        list($sfa, $count) = $this->getSplFixedArrayAndSize();
146
147
        for ($i = 0; $i < $count; $i++) {
148
            $sfa[$i] = $callback($this[$i], $i, $this);
149
        }
150
151
        return static::fromItems($sfa);
152
    }
153
154
    /**
155
     * @inheritDoc
156
     */
157
    public function reduce(callable $callback, $accumulator = null)
158
    {
159
        foreach ($this as $i => $elem) {
160
            $accumulator = $callback($accumulator, $elem, $i, $this);
161
        }
162
163
        return $accumulator;
164
    }
165
166
    /**
167
     * @inheritDoc
168
     */
169
    public function search($value)
170
    {
171
        foreach ($this as $i => $elem) {
172
            if ($value === $elem) {
173
                return $i;
174
            }
175
        }
176
    }
177
178
    /**
179
     * @inheritDoc
180
     */
181
    public function slice(int $begin = 0, int $length = null)
182
    {
183
        $end = $begin + $length;
184
        $it = new SliceIterator($this->getValues(), $begin, $end);
185
        return static::fromArray($it->toArray());
186
    }
187
188
    /**
189
     * @inheritDoc
190
     */
191
    public function splice(int $begin = 0, int $length = null, $replacement = [])
192
    {
193
        $input = $this->toArray();
194
        array_splice($input, $begin, $length, $replacement);
195
        return static::fromArray($input);
196
    }
197
198
    /**
199
     * @inheritDoc
200
     */
201
    public function sort(callable $callback = null)
202
    {
203
        if ($callback) {
204
            return $this->mergeSort($callback);
205
        }
206
207
        return $this->arraySort();
208
    }
209
210
    /**
211
     * @inheritDoc
212
     */
213
    public function walk(callable $callback)
214
    {
215
        foreach ($this as $i => $elem) {
216
            $callback($elem, $i, $this);
217
        }
218
219
        return $this;
220
    }
221
222
    abstract public static function fromItems(Traversable $array);
223
224
    abstract protected function getValues(): Traversable;
225
226
    abstract public function count(): int;
227
228
    abstract public function current();
229
230
    abstract public function next();
231
232
    abstract public function rewind();
233
234
    abstract public function valid();
235
}
236