Passed
Push — master ( c38e78...642601 )
by Stephen
50s queued 12s
created

ArrayUtility::set()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
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
     * @return self
91
     */
92
    public function flattenKeys(bool $nest_keys = true): self
93
    {
94
        // todo: possible use while loop for multi level nesting?
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.'_'.$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 modifying the original array.
134
     *
135
     * @param array $except
136
     * @return self
137
     */
138
    public function except(array $except): self
139
    {
140
        return $this->set(array_diff_key($this->array, array_flip((array) $except)));
141
    }
142
143
    /**
144
     * Remove a key from an array & return the key's value.
145
     *
146
     * @param string $key
147
     * @return mixed
148
     */
149
    public function pop(string $key)
150
    {
151
        // Get the value
152
        $value = $this->array[$key];
153
154
        // Remove the value from the array
155
        unset($this->array[$key]);
156
157
        // Return the value
158
        return $value;
159
    }
160
161
    /**
162
     * Remove a key from an array & the new array without the key.
163
     *
164
     * @param array|string $keys
165
     * @return self
166
     */
167
    public function unset($keys): self
168
    {
169
        // Remove the values from the array
170
        foreach ((array) $keys as $key) {
171
            unset($this->array[$key]);
172
        }
173
174
        // Return the new array
175
        return $this->set($this->array);
176
    }
177
178
    /**
179
     * Return a flat array of values that were found in the $first array that are not found in the $second.
180
     *
181
     * @param array $array
182
     * @return self
183
     */
184
    public function diffFlat(array $array): self
185
    {
186
        $collection = collect($this->array)
187
            ->diff($array)
188
            ->flatten();
189
190
        return $this->set($collection->toArray());
191
    }
192
193
    /**
194
     * Retrieve a random array of elements.
195
     *
196
     * @param int $items
197
     * @return self
198
     */
199
    public function random(int $items): self
200
    {
201
        // Get a random array of keys
202
        $keys = array_rand($this->array, $items);
203
204
        // Return array with only the randomly selected keys
205
        return $this->set(
206
            array_filter(
207
                $this->array,
208
                function ($value, $key) use ($keys) {
209
                    return in_array($key, $keys);
0 ignored issues
show
Bug introduced by
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

209
                    return in_array($key, /** @scrutinizer ignore-type */ $keys);
Loading history...
210
                },
211
                ARRAY_FILTER_USE_BOTH
212
            )
213
        );
214
    }
215
216
    /**
217
     * Determine if all values in an array of key => value pairs are unique.
218
     *
219
     * @return bool
220
     */
221
    public function valuesUnique(): bool
222
    {
223
        try {
224
            // Count the number of unique array values
225
            // Check to see if there is more than unique array_value
226
            return count(array_unique(array_values($this->array))) >= count(array_values($this->array));
227
        }
228
229
        // Handle nested arrays by comparing number unique keys
230
        catch (\ErrorException $exception) {
231
            $values = [];
232
            $valueCount = 0;
233
            foreach (array_values($this->array) as $value) {
234
                $values = array_merge($values, $value);
235
                $valueCount += count($value);
236
            }
237
238
            return count($values) == $valueCount;
239
        }
240
    }
241
242
    /**
243
     * Determine if all array_values are equal to a certain value.
244
     *
245
     * @param mixed $value
246
     * @return bool
247
     */
248
    public function valuesEqual($value): bool
249
    {
250
        // Check if all array values are equal to a certain value
251
        return count(array_keys($this->array, $value)) == count($this->array);
252
    }
253
254
    /**
255
     * Determine if all array_values are NOT equal to a certain value.
256
     *
257
     * @param mixed $value
258
     * @return bool
259
     */
260
    public function valuesNotEqual($value): bool
261
    {
262
        return ! $this->valuesEqual($value);
263
    }
264
265
    /**
266
     * Determine if an array is multidimensional and has keys.
267
     *
268
     * @return bool
269
     */
270
    public function hasKeys(): bool
271
    {
272
        // Array doesn't have keys if the array is the same as the array values
273
        if ($this->array == array_values($this->array)) {
274
            return false;
275
        }
276
277
        return count($this->array) == count($this->array, COUNT_RECURSIVE);
278
    }
279
280
    /**
281
     * Determine if all values in an array are null.
282
     *
283
     * @return bool
284
     */
285
    public function valuesNull(): bool
286
    {
287
        return $this->valuesEqual(null);
288
    }
289
}
290