Completed
Push — master ( 44cd2c...638a5b )
by Daniel
05:15
created

Enumerator::split()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
rs 9.4286
cc 2
eloc 5
nc 2
nop 3
1
<?php
2
namespace Narrowspark\Arr;
3
4
use ArrayAccess;
5
use Narrowspark\Arr\Traits\SplitPathTrait;
6
use Narrowspark\Arr\Traits\ValueTrait;
7
8
class Enumerator
9
{
10
    use SplitPathTrait;
11
    use ValueTrait;
12
13
    /**
14
     * Return the first element in an array passing a given truth test.
15
     *
16
     * @param array    $array
17
     * @param callable $callback
18
     * @param mixed    $default
19
     *
20
     * @return mixed
21
     */
22
    public function first(array $array, callable $callback, $default = null)
23
    {
24
        foreach ($array as $key => $value) {
25
            if (call_user_func($callback, $key, $value)) {
26
                return $value;
27
            }
28
        }
29
30
        return $this->value($default);
31
    }
32
33
    /**
34
     * Return the last element in an array passing a given truth test.
35
     *
36
     * @param array    $array
37
     * @param callable $callback
38
     * @param mixed    $default
39
     *
40
     * @return mixed
41
     */
42
    public function last(array $array, callable $callback, $default = null)
43
    {
44
        return $this->first(array_reverse($array), $callback, $default);
45
    }
46
47
    /**
48
     * Get a random element from the array supplied.
49
     *
50
     * @param array $array the source array
51
     *
52
     * @return mixed
53
     */
54
    public static function random(array $array)
55
    {
56
        if (!count($array)) {
57
            return;
58
        }
59
60
        $keys = array_rand($array, 1);
61
62
        return $this->value($array[$keys]);
0 ignored issues
show
Bug introduced by
The variable $this does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
63
    }
64
65
    /**
66
     * Get a subset of the items from the given array.
67
     *
68
     * @param string[] $array
69
     * @param string[] $keys
70
     *
71
     * @return string[]
72
     */
73
    public function only(array $array, $keys)
74
    {
75
        return array_intersect_key($array, array_flip((array) $keys));
76
    }
77
78
    /**
79
     * Split an array in the given amount of pieces.
80
     *
81
     * @param array $array
82
     * @param int   $numberOfPieces
83
     * @param bool  $preserveKeys
84
     *
85
     * @return array
86
     */
87
    public function split(array $array, $numberOfPieces = 2, $preserveKeys = false)
88
    {
89
        if (count($array) === 0) {
90
            return [];
91
        }
92
93
        $splitSize = ceil(count($array) / $numberOfPieces);
94
95
        return array_chunk($array, $splitSize, $preserveKeys);
96
    }
97
98
    /**
99
     * Pluck an array of values from an array.
100
     *
101
     * @param array|\ArrayAccess $array
102
     * @param string             $value
103
     * @param string|null        $key
104
     *
105
     * @return array
106
     */
107
    public function pluck(array $array, $value, $key = null)
108
    {
109
        $results = [];
110
111
        list($value, $key) = $this->explodePluckParameters($value, $key);
112
113
        // If the key is "null", we will just append the value to the array and keep
114
        // looping. Otherwise we will key the array using the value of the key we
115
        // received from the developer. Then we'll return the final array form.
116
        if (is_null($key)) {
117
            foreach ($array as $item) {
118
                $results[] = $this->dataGet($item, $value);
119
            }
120
        } else {
121
            foreach ($array as $item) {
122
                $results[$this->dataGet($item, $key)] = $this->dataGet($item, $value);
123
            }
124
        }
125
126
        return $results;
127
    }
128
129
    /**
130
     * Filter the array using the given Closure.
131
     *
132
     * @param array    $array
133
     * @param callable $callback
134
     *
135
     * @return array
136
     */
137
    public function where(array $array, callable $callback)
138
    {
139
        $filtered = [];
140
141
        foreach ($array as $key => $value) {
142
            if (call_user_func($callback, $key, $value)) {
143
                $filtered[$key] = $value;
144
            }
145
        }
146
147
        return $filtered;
148
    }
149
150
    /**
151
     * Push an item onto the beginning of an array.
152
     *
153
     * @param array $array
154
     * @param mixed $value
155
     * @param mixed $key
156
     *
157
     * @return array
158
     */
159
    public function prepend(array $array, $value, $key = null)
160
    {
161
        if (is_null($key)) {
162
            array_unshift($array, $value);
163
        } else {
164
            $array = [$key => $value] + $array;
165
        }
166
167
        return $array;
168
    }
169
170
    /**
171
     * Get an item from an array or object using "dot" notation.
172
     *
173
     * @param mixed        $target
174
     * @param string|array $key
175
     * @param string       $default
0 ignored issues
show
Documentation introduced by
Should the type for parameter $default not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
176
     *
177
     * @return mixed
178
     */
179
    public function dataGet($target, $key, $default = null)
180
    {
181
        if (is_null($key)) {
182
            return $target;
183
        }
184
185
        $key = is_array($key) ? $key : $this->splitPath($key);
186
187
        while (($segment = array_shift($key)) !== null) {
188
            if ($segment === '*') {
189
                if (!is_array($target) && !$target instanceof ArrayAccess) {
190
                    return $this->value($default);
191
                }
192
193
                $result = $this->pluck($target, $key);
0 ignored issues
show
Documentation introduced by
$key is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $target defined by parameter $target on line 179 can also be of type object<ArrayAccess>; however, Narrowspark\Arr\Enumerator::pluck() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
194
195
                return in_array('*', $key, true) ? $this->collapse($result) : $result;
0 ignored issues
show
Bug introduced by
The method collapse() does not seem to exist on object<Narrowspark\Arr\Enumerator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
196
            }
197
198
            if (is_array($target)) {
199
                if (!array_key_exists($segment, $target)) {
200
                    return $this->value($default);
201
                }
202
203
                $target = $target[$segment];
204
            } elseif ($target instanceof ArrayAccess) {
205
                if (!isset($target[$segment])) {
206
                    return $this->value($default);
207
                }
208
209
                $target = $target[$segment];
210
            } elseif (is_object($target)) {
211
                if (!isset($target->{$segment})) {
212
                    return $this->value($default);
213
                }
214
215
                $target = $target->{$segment};
216
            } else {
217
                return $this->value($default);
218
            }
219
        }
220
221
        return $target;
222
    }
223
224
    /**
225
     * Replace a given pattern with each value in the array in sequentially.
226
     *
227
     * @param string $pattern
228
     * @param array  $replacements
229
     * @param string $subject
230
     *
231
     * @return string
232
     */
233
    public function pregReplaceSub($pattern, &$replacements, $subject)
234
    {
235
        return preg_replace_callback($pattern, function ($match) use (&$replacements) {
1 ignored issue
show
Unused Code introduced by
The parameter $match is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
236
            return array_shift($replacements);
237
        }, $subject);
238
    }
239
240
    /**
241
     * A shorter way to run a match on the array's keys rather than the values.
242
     *
243
     * @param string $pattern
244
     * @param array  $input
245
     * @param int    $flags
246
     *
247
     * @return array
248
     */
249
    public function pregGrepKeys($pattern, array $input, $flags = 0)
250
    {
251
        return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
252
    }
253
254
    /**
255
     * Explode the "value" and "key" arguments passed to "pluck".
256
     *
257
     * @param string      $value
258
     * @param string|null $key
259
     *
260
     * @return array[]
261
     */
262
    protected function explodePluckParameters($value, $key)
263
    {
264
        $value = is_array($value) ? $value : $this->splitPath($key);
265
266
        $key = is_null($key) || is_array($key) ? $key : $this->splitPath($key);
267
268
        return [$value, $key];
269
    }
270
}
271