Issues (2)

src/Utils/ArrayUtility.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Sfneal\Helpers\Arrays\Utils;
4
5
use Illuminate\Support\Collection;
6
7
class ArrayUtility
8
{
9
    /**
10
     * @var array
11
     */
12
    private $array;
13
14
    /**
15
     * ArrayHelpers constructor.
16
     *
17
     * @param array $array
18
     */
19
    public function __construct(array $array)
20
    {
21
        $this->array = $array;
22
    }
23
24
    /**
25
     * Retrieve the $array property.
26
     *
27
     * @return array
28
     */
29
    public function get(): array
30
    {
31
        return $this->array;
32
    }
33
34
    /**
35
     * Retrieve a collection instance of the $array property.
36
     *
37
     * @return Collection
38
     */
39
    public function collect(): Collection
40
    {
41
        return collect($this->array);
42
    }
43
44
    /**
45
     * Set the $array property.
46
     *
47
     * @param array $array
48
     * @return $this
49
     */
50
    protected function set(array $array): self
51
    {
52
        $this->array = $array;
53
54
        return $this;
55
    }
56
57
    /**
58
     * Returns a chunked array with calculated chunk size.
59
     *
60
     * @param int $min
61
     * @param int|null $max
62
     * @param bool $no_remainders
63
     * @param bool $preserve_keys
64
     * @return self
65
     */
66
    public function chunks(int $min = 0, int $max = null, bool $no_remainders = false, bool $preserve_keys = true): self
67
    {
68
        $chunks = array_chunk(
69
            $this->array,
70
            (new ChunkSizer(count($this->array), $min, $max))->execute(),
71
            $preserve_keys
72
        );
73
74
        // Check if the first chunk is the same length as the last chunk
75
        if ($no_remainders && count($chunks[0]) != count(array_reverse($chunks)[0])) {
76
            $remainder = array_pop($chunks);
77
            $last_chunk = array_pop($chunks);
78
79
            // Add the remainder chunk to the last equal sized chunk
80
            $chunks[] = array_merge($last_chunk, $remainder);
81
        }
82
83
        return $this->set($chunks);
84
    }
85
86
    /**
87
     * Flatten a multidimensional array into a 2D array without nested keys.
88
     *
89
     * @param bool $nest_keys
90
     * @param string $separator
91
     * @return self
92
     */
93
    public function flattenKeys(bool $nest_keys = true, string $separator = '_'): self
94
    {
95
        $flat = [];
96
        foreach (array_keys($this->array) as $key) {
97
            if (is_array($this->array[$key])) {
98
                // If the key is an array, add each children keys to flattened array
99
                foreach ($this->array[$key] as $k => $v) {
100
                    if ($nest_keys) {
101
                        $flat[$key.$separator.$k] = $v;
102
                    } else {
103
                        $flat[$k] = $v;
104
                    }
105
                }
106
            } else {
107
                $flat[$key] = $this->array[$key];
108
            }
109
        }
110
111
        return $this->set($flat);
112
    }
113
114
    /**
115
     * Remove particular keys from a multidimensional array.
116
     *
117
     * @param array|string $keys
118
     * @return self
119
     */
120
    public function removeKeys($keys): self
121
    {
122
        $all_keys = array_keys($this->array);
123
        foreach ((array) $keys as $key) {
124
            if (in_array($key, $all_keys)) {
125
                unset($this->array[$key]);
126
            }
127
        }
128
129
        return $this->set($this->array);
130
    }
131
132
    /**
133
     * Remove specific arrays of keys without altering the original $array.
134
     *
135
     * @param array $except
136
     * @return self
137
     */
138
    public function except(array $except): self
139
    {
140
        return new self(array_diff_key($this->array, array_flip((array) $except)));
141
    }
142
143
    /**
144
     * Retrieve an array with only the keys provided in the $only param.
145
     *
146
     * @param array $only
147
     * @return self
148
     */
149
    public function only(array $only): self
150
    {
151
        return $this->set(array_filter($this->array, function ($key) use ($only) {
152
            return in_array($key, $only);
153
        }, ARRAY_FILTER_USE_KEY));
154
    }
155
156
    /**
157
     * Merge arrays into the existing array.
158
     *
159
     * @param ...$arrays
160
     * @return $this
161
     */
162
    public function merge(...$arrays): self
163
    {
164
        return $this->set(array_merge($this->array, ...$arrays));
165
    }
166
167
    /**
168
     * Remove a key from an array & return the key's value.
169
     *
170
     * @param string $key
171
     * @return mixed
172
     */
173
    public function pop(string $key)
174
    {
175
        // Get the value
176
        $value = $this->array[$key];
177
178
        // Remove the value from the array
179
        unset($this->array[$key]);
180
181
        // Return the value
182
        return $value;
183
    }
184
185
    /**
186
     * Remove a key from an array & the new array without the key.
187
     *
188
     * @param array|string $keys
189
     * @return self
190
     */
191
    public function unset($keys): self
192
    {
193
        // Remove the values from the array
194
        foreach ((array) $keys as $key) {
195
            unset($this->array[$key]);
196
        }
197
198
        // Return the new array
199
        return $this->set($this->array);
200
    }
201
202
    /**
203
     * Return a flat array of values that were found in the $first array that are not found in the $second.
204
     *
205
     * @param array $array
206
     * @return self
207
     */
208
    public function diffFlat(array $array): self
209
    {
210
        $collection = collect($this->array)
211
            ->diff($array)
212
            ->flatten();
213
214
        return $this->set($collection->toArray());
215
    }
216
217
    /**
218
     * Retrieve a random array of elements.
219
     *
220
     * @param int $items
221
     * @return self
222
     */
223
    public function random(int $items): self
224
    {
225
        // Get a random array of keys
226
        $keys = array_rand($this->array, $items);
227
228
        // Return array with only the randomly selected keys
229
        return $this->set(
230
            array_filter(
231
                $this->array,
232
                function ($value, $key) use ($keys) {
233
                    return in_array($key, $keys);
0 ignored issues
show
It seems like $keys can also be of type integer and string; however, parameter $haystack of in_array() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

233
                    return in_array($key, /** @scrutinizer ignore-type */ $keys);
Loading history...
234
                },
235
                ARRAY_FILTER_USE_BOTH
236
            )
237
        );
238
    }
239
240
    /**
241
     * Determine if all values in an array of key => value pairs are unique.
242
     *
243
     * @return bool
244
     */
245
    public function valuesUnique(): bool
246
    {
247
        try {
248
            // Count the number of unique array values
249
            // Check to see if there is more than unique array_value
250
            return count(array_unique(array_values($this->array))) >= count(array_values($this->array));
251
        }
252
253
        // Handle nested arrays by comparing number unique keys
254
        catch (\ErrorException $exception) {
255
            $values = [];
256
            $valueCount = 0;
257
            foreach (array_values($this->array) as $value) {
258
                $values = array_merge($values, $value);
259
                $valueCount += count($value);
260
            }
261
262
            return count($values) == $valueCount;
263
        }
264
    }
265
266
    /**
267
     * Determine if all array_values are equal to a certain value.
268
     *
269
     * @param mixed $value
270
     * @return bool
271
     */
272
    public function valuesEqual($value): bool
273
    {
274
        // Check if all array values are equal to a certain value
275
        return count(array_keys($this->array, $value)) == count($this->array);
276
    }
277
278
    /**
279
     * Determine if all array_values are NOT equal to a certain value.
280
     *
281
     * @param mixed $value
282
     * @return bool
283
     */
284
    public function valuesNotEqual($value): bool
285
    {
286
        return ! $this->valuesEqual($value);
287
    }
288
289
    /**
290
     * Determine if an array is multidimensional and has keys.
291
     *
292
     * @return bool
293
     */
294
    public function hasKeys(): bool
295
    {
296
        // Array doesn't have keys if the array is the same as the array values
297
        if ($this->array == array_values($this->array)) {
298
            return false;
299
        }
300
301
        return count($this->array) == count($this->array, COUNT_RECURSIVE);
302
    }
303
304
    /**
305
     * Determine if all values in an array are null.
306
     *
307
     * @return bool
308
     */
309
    public function valuesNull(): bool
310
    {
311
        return $this->valuesEqual(null);
312
    }
313
}
314