1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Arrayy; |
4
|
|
|
|
5
|
|
|
use ArrayAccess; |
6
|
|
|
use voku\helper\UTF8; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Methods to manage arrays. |
10
|
|
|
*/ |
11
|
|
|
class Arrayy extends CollectionMethods implements \Countable, \IteratorAggregate, \ArrayAccess |
12
|
|
|
{ |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @var array |
16
|
|
|
*/ |
17
|
|
|
private $array = array(); |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Initializes |
21
|
|
|
* |
22
|
|
|
* @param array $array |
23
|
|
|
*/ |
24
|
244 |
|
public function __construct($array = array()) |
25
|
|
|
{ |
26
|
244 |
|
if (!$array) { |
|
|
|
|
27
|
52 |
|
$array = array(); |
28
|
52 |
|
} |
29
|
|
|
|
30
|
|
|
if ( |
31
|
244 |
|
is_string($array) |
32
|
|
|
|| |
33
|
244 |
|
(is_object($array) && method_exists($array, '__toString')) |
34
|
244 |
|
) { |
35
|
1 |
|
$array = (array)$array; |
36
|
1 |
|
} |
37
|
|
|
|
38
|
244 |
|
if (!is_array($array)) { |
39
|
2 |
|
throw new \InvalidArgumentException( |
40
|
|
|
'Passed value must be a array' |
41
|
2 |
|
); |
42
|
|
|
} |
43
|
|
|
|
44
|
242 |
|
$this->array = $array; |
45
|
242 |
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* magic to string |
49
|
|
|
* |
50
|
|
|
* @return string |
51
|
|
|
*/ |
52
|
13 |
|
public function __toString() |
53
|
|
|
{ |
54
|
13 |
|
return $this->implode(','); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Get a data by key |
59
|
|
|
* |
60
|
|
|
* @param $key |
61
|
|
|
* |
62
|
|
|
* @return mixed |
63
|
|
|
*/ |
64
|
|
|
public function &__get($key) |
65
|
|
|
{ |
66
|
|
|
return $this->array[$key]; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Assigns a value to the specified data |
71
|
|
|
* |
72
|
|
|
* @param $key |
73
|
|
|
* @param $value |
74
|
|
|
*/ |
75
|
|
|
public function __set($key, $value) |
76
|
|
|
{ |
77
|
|
|
$this->array[$key] = $value; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Whether or not an data exists by key |
82
|
|
|
* |
83
|
|
|
* @param $key |
84
|
|
|
* |
85
|
|
|
* @return bool |
86
|
|
|
*/ |
87
|
|
|
public function __isset($key) |
88
|
|
|
{ |
89
|
|
|
return isset($this->array[$key]); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Unsets an data by key |
94
|
|
|
* |
95
|
|
|
* @param mixed $key |
96
|
|
|
*/ |
97
|
|
|
public function __unset($key) |
98
|
|
|
{ |
99
|
|
|
unset($this->array[$key]); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Assigns a value to the specified offset |
104
|
|
|
* |
105
|
|
|
* |
106
|
|
|
* @param mixed $offset |
107
|
|
|
* @param mixed $value |
108
|
|
|
*/ |
109
|
|
|
public function offsetSet($offset, $value) |
110
|
|
|
{ |
111
|
|
|
if (null === $offset) { |
112
|
|
|
$this->array[] = $value; |
113
|
|
|
} else { |
114
|
|
|
$this->array[$offset] = $value; |
115
|
|
|
} |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Whether or not an offset exists |
120
|
|
|
* |
121
|
|
|
* @param mixed $offset |
122
|
|
|
* |
123
|
|
|
* @return bool |
124
|
|
|
*/ |
125
|
3 |
|
public function offsetExists($offset) |
126
|
|
|
{ |
127
|
3 |
|
return isset($this->array[$offset]); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Unsets an offset |
132
|
|
|
* |
133
|
|
|
* @param mixed $offset |
134
|
|
|
*/ |
135
|
|
|
public function offsetUnset($offset) |
136
|
|
|
{ |
137
|
|
|
if ($this->offsetExists($offset)) { |
138
|
|
|
unset($this->array[$offset]); |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Returns the value at specified offset |
144
|
|
|
* |
145
|
|
|
* @param mixed $offset |
146
|
|
|
* |
147
|
|
|
* @return null |
148
|
|
|
*/ |
149
|
3 |
|
public function offsetGet($offset) |
150
|
|
|
{ |
151
|
3 |
|
return $this->offsetExists($offset) ? $this->array[$offset] : null; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Returns a new ArrayIterator, thus implementing the IteratorAggregate |
156
|
|
|
* interface. |
157
|
|
|
* |
158
|
|
|
* @return \ArrayIterator An iterator for the values in the array |
159
|
|
|
*/ |
160
|
1 |
|
public function getIterator() |
161
|
|
|
{ |
162
|
1 |
|
return new \ArrayIterator($this->array); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* call object as function |
167
|
|
|
* |
168
|
|
|
* @param mixed $key |
169
|
|
|
* |
170
|
|
|
* @return mixed |
171
|
|
|
*/ |
172
|
|
|
public function __invoke($key = null) |
173
|
|
|
{ |
174
|
|
|
if ($key !== null) { |
175
|
|
|
if (isset($this->array[$key])) { |
176
|
|
|
return $this->array[$key]; |
177
|
|
|
} else { |
178
|
|
|
return false; |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
return (array)$this->array; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* get the current array from the "Arrayy"-object |
187
|
|
|
* |
188
|
|
|
* @return array |
189
|
|
|
*/ |
190
|
144 |
|
public function getArray() |
191
|
|
|
{ |
192
|
144 |
|
return $this->array; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
/** |
196
|
|
|
* Creates a Arrayy object |
197
|
|
|
* |
198
|
|
|
* @param array $array |
199
|
|
|
* |
200
|
|
|
* @return self |
201
|
|
|
*/ |
202
|
185 |
|
public static function create($array = array()) |
203
|
|
|
{ |
204
|
185 |
|
return new static($array); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
//////////////////////////////////////////////////////////////////// |
208
|
|
|
///////////////////////////// ANALYZE ////////////////////////////// |
209
|
|
|
//////////////////////////////////////////////////////////////////// |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* Search for the value of the current array via $index. |
213
|
|
|
* |
214
|
|
|
* @param mixed $index |
215
|
|
|
* |
216
|
|
|
* @return self |
217
|
|
|
*/ |
218
|
7 |
|
public function searchValue($index) |
219
|
|
|
{ |
220
|
|
|
// init |
221
|
7 |
|
$return = array(); |
222
|
|
|
|
223
|
7 |
|
if (null !== $index) { |
224
|
7 |
|
$keyExists = isset($this->array[$index]); |
225
|
|
|
|
226
|
7 |
|
if ($keyExists !== false) { |
227
|
5 |
|
$return = array($this->array[$index]); |
228
|
5 |
|
} |
229
|
7 |
|
} |
230
|
|
|
|
231
|
7 |
|
return self::create((array)$return); |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* Search for the index of the current array via $value. |
236
|
|
|
* |
237
|
|
|
* @param mixed $value |
238
|
|
|
* |
239
|
|
|
* @return self |
240
|
|
|
*/ |
241
|
7 |
|
public function searchIndex($value) |
242
|
|
|
{ |
243
|
7 |
|
$key = array_search($value, $this->array, true); |
244
|
|
|
|
245
|
7 |
|
if ($key === false) { |
246
|
2 |
|
$return = array(); |
247
|
2 |
|
} else { |
248
|
5 |
|
$return = array($key); |
249
|
|
|
} |
250
|
|
|
|
251
|
7 |
|
return self::create((array)$return); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Check if all items in an array match a truth test. |
256
|
|
|
* |
257
|
|
|
* @param \Closure $closure |
258
|
|
|
* |
259
|
|
|
* @return bool |
260
|
|
|
*/ |
261
|
8 |
View Code Duplication |
public function matches(\Closure $closure) |
|
|
|
|
262
|
|
|
{ |
263
|
|
|
// Reduce the array to only booleans |
264
|
8 |
|
$array = $this->each($closure); |
265
|
|
|
|
266
|
|
|
// Check the results |
267
|
8 |
|
if (count($array) === 0) { |
268
|
2 |
|
return true; |
269
|
|
|
} |
270
|
6 |
|
$array = array_search(false, $array, false); |
271
|
|
|
|
272
|
6 |
|
return is_bool($array); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* Check if any item in an array matches a truth test. |
277
|
|
|
* |
278
|
|
|
* @param \Closure $closure |
279
|
|
|
* |
280
|
|
|
* @return bool |
281
|
|
|
*/ |
282
|
8 |
View Code Duplication |
public function matchesAny(\Closure $closure) |
|
|
|
|
283
|
|
|
{ |
284
|
|
|
// Reduce the array to only booleans |
285
|
8 |
|
$array = $this->each($closure); |
286
|
|
|
|
287
|
|
|
// Check the results |
288
|
8 |
|
if (count($array) === 0) { |
289
|
2 |
|
return true; |
290
|
|
|
} |
291
|
6 |
|
$array = array_search(true, $array, false); |
292
|
|
|
|
293
|
6 |
|
return is_int($array); |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* Check if an item is in an array. |
298
|
|
|
* |
299
|
|
|
* @param mixed $value |
300
|
|
|
* |
301
|
|
|
* @return bool |
302
|
|
|
*/ |
303
|
9 |
|
public function contains($value) |
304
|
|
|
{ |
305
|
9 |
|
return in_array($value, $this->array, true); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* Returns the average value of an array. |
310
|
|
|
* |
311
|
|
|
* @param int $decimals The number of decimals to return |
312
|
|
|
* |
313
|
|
|
* @return int The average value |
314
|
|
|
*/ |
315
|
10 |
|
public function average($decimals = null) |
316
|
|
|
{ |
317
|
10 |
|
$count = $this->count(); |
318
|
|
|
|
319
|
10 |
|
if (!$count) { |
320
|
2 |
|
return 0; |
321
|
|
|
} |
322
|
|
|
|
323
|
8 |
|
if (!is_int($decimals)) { |
324
|
3 |
|
$decimals = null; |
325
|
3 |
|
} |
326
|
|
|
|
327
|
8 |
|
return round(array_sum($this->array) / $count, $decimals); |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
/** |
331
|
|
|
* Count the values from the current array. |
332
|
|
|
* |
333
|
|
|
* INFO: only a alias for "$arrayy->size()" |
334
|
|
|
* |
335
|
|
|
* @return int |
336
|
|
|
*/ |
337
|
|
|
public function length() |
338
|
|
|
{ |
339
|
|
|
return $this->size(); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* Count the values from the current array. |
344
|
|
|
* |
345
|
|
|
* INFO: only a alias for "$arrayy->size()" |
346
|
|
|
* |
347
|
|
|
* @return int |
348
|
|
|
*/ |
349
|
40 |
|
public function count() |
350
|
|
|
{ |
351
|
40 |
|
return $this->size(); |
352
|
|
|
} |
353
|
|
|
|
354
|
|
|
/** |
355
|
|
|
* Get the size of an array. |
356
|
|
|
* |
357
|
|
|
* @return int |
358
|
|
|
*/ |
359
|
40 |
|
public function size() |
360
|
|
|
{ |
361
|
40 |
|
return count($this->array); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* Get the max value from an array. |
366
|
|
|
* |
367
|
|
|
* @return mixed |
368
|
|
|
*/ |
369
|
10 |
|
public function max() |
370
|
|
|
{ |
371
|
10 |
|
if ($this->count() === 0) { |
372
|
1 |
|
return false; |
373
|
|
|
} |
374
|
|
|
|
375
|
9 |
|
return max($this->array); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
/** |
379
|
|
|
* Get the min value from an array. |
380
|
|
|
* |
381
|
|
|
* @return mixed |
382
|
|
|
*/ |
383
|
10 |
|
public function min() |
384
|
|
|
{ |
385
|
10 |
|
if ($this->count() === 0) { |
386
|
1 |
|
return false; |
387
|
|
|
} |
388
|
|
|
|
389
|
9 |
|
return min($this->array); |
390
|
|
|
} |
391
|
|
|
|
392
|
|
|
//////////////////////////////////////////////////////////////////// |
393
|
|
|
//////////////////////////// FETCH FROM //////////////////////////// |
394
|
|
|
//////////////////////////////////////////////////////////////////// |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* Find the first item in an array that passes the truth test, |
398
|
|
|
* otherwise return false |
399
|
|
|
* |
400
|
|
|
* @param \Closure $closure |
401
|
|
|
* |
402
|
|
|
* @return mixed|false false if we couldn't find the value |
403
|
|
|
*/ |
404
|
7 |
|
public function find(\Closure $closure) |
405
|
|
|
{ |
406
|
7 |
|
foreach ($this->array as $key => $value) { |
407
|
5 |
|
if ($closure($value, $key)) { |
408
|
4 |
|
return $value; |
409
|
|
|
} |
410
|
4 |
|
} |
411
|
|
|
|
412
|
3 |
|
return false; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Clean all falsy values from an array. |
417
|
|
|
* |
418
|
|
|
* @return self |
419
|
|
|
*/ |
420
|
7 |
|
public function clean() |
421
|
|
|
{ |
422
|
7 |
|
return $this->filter( |
423
|
|
|
function ($value) { |
424
|
6 |
|
return (bool)$value; |
425
|
|
|
} |
426
|
7 |
|
); |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
/** |
430
|
|
|
* Get a random string from an array. |
431
|
|
|
* |
432
|
|
|
* @param null $take |
433
|
|
|
* |
434
|
|
|
* @return self |
435
|
|
|
*/ |
436
|
5 |
|
public function random($take = null) |
437
|
|
|
{ |
438
|
5 |
|
if ($take !== null) { |
439
|
|
|
return $this->array[array_rand($this->array)]; |
440
|
|
|
} |
441
|
|
|
|
442
|
5 |
|
shuffle($this->array); |
443
|
|
|
|
444
|
5 |
|
return $this->first($take); |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* Return an array with all elements found in input array. |
449
|
|
|
* |
450
|
|
|
* @param array $search |
451
|
|
|
* |
452
|
|
|
* @return self |
453
|
|
|
*/ |
454
|
2 |
|
public function intersection(array $search) |
455
|
|
|
{ |
456
|
2 |
|
return self::create(array_values(array_intersect($this->array, $search))); |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* Return a boolean flag which indicates whether the two input arrays have any common elements. |
461
|
|
|
* |
462
|
|
|
* @param array $search |
463
|
|
|
* |
464
|
|
|
* @return bool |
465
|
|
|
*/ |
466
|
1 |
|
public function intersects(array $search) |
467
|
|
|
{ |
468
|
1 |
|
return count($this->intersection($search)->array) > 0; |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
//////////////////////////////////////////////////////////////////// |
472
|
|
|
///////////////////////////// SLICERS ////////////////////////////// |
473
|
|
|
//////////////////////////////////////////////////////////////////// |
474
|
|
|
|
475
|
|
|
/** |
476
|
|
|
* Get the first value from an array. |
477
|
|
|
* |
478
|
|
|
* @param int|null $take |
479
|
|
|
* |
480
|
|
|
* @return self |
481
|
|
|
*/ |
482
|
27 |
|
public function first($take = null) |
483
|
|
|
{ |
484
|
27 |
|
if ($take === null) { |
485
|
13 |
|
$array = array_shift($this->array); |
486
|
13 |
|
} else { |
487
|
14 |
|
$array = array_splice($this->array, 0, $take, true); |
488
|
|
|
} |
489
|
|
|
|
490
|
27 |
|
return self::create((array)$array); |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
/** |
494
|
|
|
* Get the last value from an array. |
495
|
|
|
* |
496
|
|
|
* @param int|null $take |
497
|
|
|
* |
498
|
|
|
* @return self |
499
|
|
|
*/ |
500
|
10 |
|
public function last($take = null) |
501
|
|
|
{ |
502
|
10 |
|
if ($take === null) { |
503
|
7 |
|
$array = self::create((array)array_pop($this->array)); |
504
|
7 |
|
} else { |
505
|
3 |
|
$array = $this->rest(-$take); |
506
|
|
|
} |
507
|
|
|
|
508
|
10 |
|
return $array; |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
/** |
512
|
|
|
* Get everything but the last..$to items. |
513
|
|
|
* |
514
|
|
|
* @param int $to |
515
|
|
|
* |
516
|
|
|
* @return self |
517
|
|
|
*/ |
518
|
10 |
|
public function initial($to = 1) |
519
|
|
|
{ |
520
|
10 |
|
$slice = count($this->array) - $to; |
521
|
|
|
|
522
|
10 |
|
return $this->first($slice); |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
/** |
526
|
|
|
* Get the last elements from index $from. |
527
|
|
|
* |
528
|
|
|
* @param int $from |
529
|
|
|
* |
530
|
|
|
* @return self |
531
|
|
|
*/ |
532
|
13 |
|
public function rest($from = 1) |
533
|
|
|
{ |
534
|
13 |
|
return self::create(array_splice($this->array, $from)); |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
//////////////////////////////////////////////////////////////////// |
538
|
|
|
///////////////////////////// ACT UPON ///////////////////////////// |
539
|
|
|
//////////////////////////////////////////////////////////////////// |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* Iterate over an array and execute a callback for each loop. |
543
|
|
|
* |
544
|
|
|
* @param \Closure $closure |
545
|
|
|
* |
546
|
|
|
* @return mixed |
547
|
|
|
*/ |
548
|
1 |
View Code Duplication |
public function at(\Closure $closure) |
|
|
|
|
549
|
|
|
{ |
550
|
1 |
|
$array = $this->array; |
551
|
|
|
|
552
|
1 |
|
foreach ($array as $key => $value) { |
553
|
1 |
|
$closure($value, $key); |
554
|
1 |
|
} |
555
|
|
|
|
556
|
1 |
|
return self::create($array); |
557
|
|
|
} |
558
|
|
|
|
559
|
|
|
//////////////////////////////////////////////////////////////////// |
560
|
|
|
////////////////////////////// ALTER /////////////////////////////// |
561
|
|
|
//////////////////////////////////////////////////////////////////// |
562
|
|
|
|
563
|
|
|
/** |
564
|
|
|
* Merge the new $array into the current array, replace already existing keys |
565
|
|
|
* from the current array with the key,values from the new $array |
566
|
|
|
* and create new indexes. |
567
|
|
|
* |
568
|
|
|
* @param array $array |
569
|
|
|
* |
570
|
|
|
* @return self |
571
|
|
|
*/ |
572
|
8 |
|
public function mergeAppendNewIndex(array $array = array()) |
573
|
|
|
{ |
574
|
8 |
|
return self::create(array_merge($this->array, $array)); |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
/** |
578
|
|
|
* Merge the current array into the new $array, replace already existing keys |
579
|
|
|
* from new $array with the key,values from the current array |
580
|
|
|
* and create new indexes. |
581
|
|
|
* |
582
|
|
|
* @param array $array |
583
|
|
|
* |
584
|
|
|
* @return self |
585
|
|
|
*/ |
586
|
|
|
public function mergePrependNewIndex(array $array = array()) |
587
|
|
|
{ |
588
|
|
|
return self::create(array_merge($array, $this->array)); |
589
|
|
|
} |
590
|
|
|
|
591
|
|
|
/** |
592
|
|
|
* Merge the new $array into the current array and |
593
|
|
|
* keep keys and values from the current array. |
594
|
|
|
* |
595
|
|
|
* @param array $array |
596
|
|
|
* |
597
|
|
|
* @return self |
598
|
|
|
*/ |
599
|
|
|
public function mergeAppendKeepIndex(array $array = array()) |
600
|
|
|
{ |
601
|
|
|
/** @noinspection AdditionOperationOnArraysInspection */ |
602
|
|
|
return self::create($this->array + $array); |
603
|
|
|
} |
604
|
|
|
|
605
|
|
|
/** |
606
|
|
|
* Merge the the current array into the $array, keep keys and values from the new $array. |
607
|
|
|
* |
608
|
|
|
* @param array $array |
609
|
|
|
* |
610
|
|
|
* @return self |
611
|
|
|
*/ |
612
|
|
|
public function mergePrependKeepIndex(array $array = array()) |
613
|
|
|
{ |
614
|
|
|
/** @noinspection AdditionOperationOnArraysInspection */ |
615
|
|
|
return self::create($array + $this->array); |
616
|
|
|
} |
617
|
|
|
|
618
|
|
|
/** |
619
|
|
|
* Merge the new $array into the current array, keep keys from the current array |
620
|
|
|
* and overwrite values with the new $array. |
621
|
|
|
* |
622
|
|
|
* @param $array |
623
|
|
|
* |
624
|
|
|
* @return self |
625
|
|
|
*/ |
626
|
|
|
public function mergeReplaceAppend(array $array = array()) |
627
|
|
|
{ |
628
|
|
|
return self::create(array_replace($this->array, $array)); |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
/** |
632
|
|
|
* Merge the the current array into the $array, keep keys from the new $array |
633
|
|
|
* and overwrite values with the old from the current array. |
634
|
|
|
* |
635
|
|
|
* @param $array |
636
|
|
|
* |
637
|
|
|
* @return self |
638
|
|
|
*/ |
639
|
|
|
public function mergeReplacePrepend(array $array = array()) |
640
|
|
|
{ |
641
|
|
|
return self::create(array_replace($array, $this->array)); |
642
|
|
|
} |
643
|
|
|
|
644
|
|
|
/** |
645
|
|
|
* Return values that are only in the current array. |
646
|
|
|
* |
647
|
|
|
* @param array $array |
648
|
|
|
* |
649
|
|
|
* @return self |
650
|
|
|
*/ |
651
|
|
|
public function diff(array $array = array()) |
652
|
|
|
{ |
653
|
|
|
return self::create(array_diff($this->array, $array)); |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
/** |
657
|
|
|
* Return values that are only in the new $array. |
658
|
|
|
* |
659
|
|
|
* @param array $array |
660
|
|
|
* |
661
|
|
|
* @return self |
662
|
|
|
*/ |
663
|
|
|
public function diffReverse(array $array = array()) |
664
|
|
|
{ |
665
|
|
|
return self::create(array_diff($array, $this->array)); |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
/** |
669
|
|
|
* Replace a value in an array. |
670
|
|
|
* |
671
|
|
|
* @param string $search The string to replace |
672
|
|
|
* @param string $replacement What to replace it with |
673
|
|
|
* |
674
|
|
|
* @return self |
675
|
|
|
*/ |
676
|
3 |
|
public function replaceValue($search, $replacement = '') |
677
|
|
|
{ |
678
|
3 |
|
$array = $this->array; |
679
|
|
|
$key = array_search($search, $array, true); |
680
|
3 |
|
|
681
|
|
|
if ($key !== false) { |
682
|
3 |
|
$array[$key] = $replacement; |
683
|
|
|
} |
684
|
3 |
|
|
685
|
|
|
return self::create((array)$array); |
686
|
|
|
} |
687
|
|
|
|
688
|
|
|
/** |
689
|
|
|
* Replace values in an array. |
690
|
|
|
* |
691
|
|
|
* @param string $search The string to replace |
692
|
|
|
* @param string $replacement What to replace it with |
693
|
|
|
* |
694
|
1 |
|
* @return self |
695
|
|
|
*/ |
696
|
1 |
|
public function replaceValues($search, $replacement = '') |
697
|
|
|
{ |
698
|
1 |
|
$array = $this->each( |
699
|
|
|
function ($value) use ($search, $replacement) { |
700
|
|
|
return UTF8::str_replace($search, $replacement, $value); |
701
|
|
|
} |
702
|
|
|
); |
703
|
|
|
|
704
|
|
|
return self::create((array)$array); |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
/** |
708
|
20 |
|
* Replace the keys in an array with another set. |
709
|
|
|
* |
710
|
20 |
|
* @param array $keys An array of keys matching the array's size |
711
|
|
|
* |
712
|
20 |
|
* @return self |
713
|
16 |
|
*/ |
714
|
20 |
|
public function replaceKeys(array $keys) |
715
|
|
|
{ |
716
|
20 |
|
$values = array_values($this->array); |
717
|
|
|
|
718
|
|
|
return self::create(array_combine($keys, $values)); |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
/** |
722
|
|
|
* Iterate over an array and modify the array's value. |
723
|
|
|
* |
724
|
1 |
|
* @param \Closure $closure |
725
|
|
|
* |
726
|
1 |
|
* @return array |
727
|
|
|
*/ |
728
|
1 |
View Code Duplication |
public function each(\Closure $closure) |
|
|
|
|
729
|
|
|
{ |
730
|
1 |
|
$array = $this->array; |
731
|
|
|
|
732
|
|
|
foreach ($array as $key => &$value) { |
733
|
|
|
$value = $closure($value, $key); |
734
|
|
|
} |
735
|
|
|
|
736
|
|
|
return $array; |
737
|
|
|
} |
738
|
|
|
|
739
|
|
|
/** |
740
|
8 |
|
* Shuffle an array. |
741
|
|
|
* |
742
|
8 |
|
* @return self |
743
|
8 |
|
*/ |
744
|
|
|
public function shuffle() |
745
|
8 |
|
{ |
746
|
1 |
|
$array = $this->array; |
747
|
1 |
|
|
748
|
7 |
|
shuffle($array); |
749
|
|
|
|
750
|
|
|
return self::create($array); |
751
|
8 |
|
} |
752
|
7 |
|
|
753
|
7 |
|
/** |
754
|
1 |
|
* Sort an array by key. |
755
|
|
|
* |
756
|
|
|
* @param string $direction |
757
|
8 |
|
* |
758
|
|
|
* @return self |
759
|
|
|
*/ |
760
|
|
|
public function sortKeys($direction = 'ASC') |
761
|
|
|
{ |
762
|
|
|
$array = $this->array; |
763
|
|
|
$direction = strtolower($direction); |
764
|
|
|
|
765
|
|
|
if ($direction === 'desc') { |
766
|
|
|
$directionType = SORT_DESC; |
767
|
21 |
|
} else { |
768
|
|
|
$directionType = SORT_ASC; |
769
|
21 |
|
} |
770
|
|
|
|
771
|
|
|
if ($directionType === SORT_ASC) { |
772
|
|
|
ksort($array); |
773
|
|
|
} else { |
774
|
|
|
krsort($array); |
775
|
|
|
} |
776
|
|
|
|
777
|
|
|
return self::create($array); |
778
|
|
|
} |
779
|
8 |
|
|
780
|
|
|
/** |
781
|
8 |
|
* Implodes an array. |
782
|
|
|
* |
783
|
|
|
* @param string $with What to implode it with |
784
|
|
|
* |
785
|
8 |
|
* @return string |
786
|
|
|
*/ |
787
|
8 |
|
public function implode($with = '') |
788
|
|
|
{ |
789
|
|
|
return implode($with, $this->array); |
790
|
|
|
} |
791
|
|
|
|
792
|
|
|
/** |
793
|
|
|
* Find all items in an array that pass the truth test. |
794
|
|
|
* |
795
|
|
|
* @param null $closure |
796
|
|
|
* |
797
|
|
|
* @return self |
798
|
1 |
|
*/ |
799
|
|
|
public function filter($closure = null) |
800
|
|
|
{ |
801
|
1 |
|
if (!$closure) { |
802
|
1 |
|
return $this->clean(); |
803
|
1 |
|
} |
804
|
|
|
|
805
|
|
|
$array = array_filter($this->array, $closure); |
806
|
1 |
|
|
807
|
1 |
|
return self::create($array); |
808
|
1 |
|
} |
809
|
1 |
|
|
810
|
|
|
/** |
811
|
|
|
* Invoke a function on all of an array's values. |
812
|
1 |
|
* |
813
|
|
|
* @param mixed $callable |
814
|
|
|
* @param array $arguments |
815
|
|
|
* |
816
|
|
|
* @return self |
817
|
|
|
*/ |
818
|
|
|
public function invoke($callable, $arguments = array()) |
819
|
|
|
{ |
820
|
|
|
// If one argument given for each iteration, create an array for it. |
821
|
|
|
if (!is_array($arguments)) { |
822
|
1 |
|
$arguments = StaticArrayy::repeat($arguments, count($this->array))->getArray(); |
823
|
|
|
} |
824
|
1 |
|
|
825
|
|
|
// If the callable has arguments, pass them. |
826
|
1 |
|
if ($arguments) { |
|
|
|
|
827
|
1 |
|
$array = array_map($callable, $this->array, $arguments); |
828
|
1 |
|
} else { |
829
|
1 |
|
$array = array_map($callable, $this->array); |
830
|
1 |
|
} |
831
|
|
|
|
832
|
1 |
|
return self::create($array); |
833
|
|
|
} |
834
|
|
|
|
835
|
|
|
/** |
836
|
|
|
* Return all items that fail the truth test. |
837
|
|
|
* |
838
|
|
|
* @param \Closure $closure |
839
|
|
|
* |
840
|
8 |
|
* @return self |
841
|
|
|
*/ |
842
|
8 |
View Code Duplication |
public function reject(\Closure $closure) |
|
|
|
|
843
|
|
|
{ |
844
|
8 |
|
$filtered = array(); |
845
|
|
|
|
846
|
|
|
foreach ($this->array as $key => $value) { |
847
|
|
|
if (!$closure($value, $key)) { |
848
|
|
|
$filtered[$key] = $value; |
849
|
|
|
} |
850
|
|
|
} |
851
|
|
|
|
852
|
7 |
|
return self::create($filtered); |
853
|
|
|
} |
854
|
7 |
|
|
855
|
|
|
/** |
856
|
7 |
|
* Remove the first value from an array. |
857
|
|
|
* |
858
|
|
|
* @return self |
859
|
|
|
*/ |
860
|
|
|
public function removeFirst() |
861
|
|
|
{ |
862
|
|
|
array_shift($this->array); |
863
|
|
|
|
864
|
|
|
return self::create($this->array); |
865
|
|
|
} |
866
|
7 |
|
|
867
|
|
|
/** |
868
|
7 |
|
* Remove the last value from an array. |
869
|
7 |
|
* |
870
|
6 |
|
* @return self |
871
|
6 |
|
*/ |
872
|
|
|
public function removeLast() |
873
|
|
|
{ |
874
|
6 |
|
array_pop($this->array); |
875
|
6 |
|
|
876
|
7 |
|
return self::create($this->array); |
877
|
|
|
} |
878
|
7 |
|
|
879
|
7 |
|
/** |
880
|
7 |
|
* Removes a particular value from an array (numeric or associative). |
881
|
|
|
* |
882
|
7 |
|
* @param mixed $value |
883
|
|
|
* |
884
|
|
|
* @return self |
885
|
|
|
*/ |
886
|
|
|
public function removeValue($value) |
887
|
|
|
{ |
888
|
|
|
$isNumericArray = true; |
889
|
|
|
foreach ($this->array as $key => $item) { |
890
|
|
|
if ($item === $value) { |
891
|
|
|
if (!is_int($key)) { |
892
|
7 |
|
$isNumericArray = false; |
893
|
|
|
} |
894
|
7 |
|
unset($this->array[$key]); |
895
|
|
|
} |
896
|
7 |
|
} |
897
|
|
|
|
898
|
|
|
if ($isNumericArray) { |
899
|
|
|
$this->array = array_values($this->array); |
900
|
|
|
} |
901
|
|
|
|
902
|
|
|
return self::create($this->array); |
903
|
|
|
} |
904
|
|
|
|
905
|
|
|
/** |
906
|
8 |
|
* Prepend a value to an array. |
907
|
|
|
* |
908
|
8 |
|
* @param mixed $value |
909
|
|
|
* |
910
|
8 |
|
* @return self |
911
|
|
|
*/ |
912
|
|
|
public function prepend($value) |
913
|
|
|
{ |
914
|
|
|
array_unshift($this->array, $value); |
915
|
|
|
|
916
|
|
|
return self::create($this->array); |
917
|
|
|
} |
918
|
7 |
|
|
919
|
|
|
/** |
920
|
7 |
|
* Append a value to an array. |
921
|
|
|
* |
922
|
7 |
|
* @param mixed $value |
923
|
|
|
* |
924
|
|
|
* @return self |
925
|
|
|
*/ |
926
|
|
|
public function append($value) |
927
|
|
|
{ |
928
|
|
|
$this->array[] = $value; |
929
|
|
|
|
930
|
7 |
|
return self::create($this->array); |
931
|
|
|
} |
932
|
7 |
|
|
933
|
7 |
|
/** |
934
|
7 |
|
* Return the array in the reverse order. |
935
|
6 |
|
* |
936
|
6 |
|
* @return self |
937
|
6 |
|
*/ |
938
|
|
|
public function reverse() |
939
|
6 |
|
{ |
940
|
7 |
|
$this->array = array_reverse($this->array); |
941
|
7 |
|
|
942
|
7 |
|
return self::create($this->array); |
943
|
|
|
} |
944
|
7 |
|
|
945
|
|
|
/** |
946
|
|
|
* duplicate free copy of an array |
947
|
|
|
* |
948
|
|
|
* @return self |
949
|
|
|
*/ |
950
|
|
|
public function unique() |
951
|
|
|
{ |
952
|
|
|
$this->array = array_reduce( |
|
|
|
|
953
|
|
|
$this->array, |
954
|
|
|
function ($resultArray, $value) { |
955
|
|
|
if (in_array($value, $resultArray, true) === false) { |
956
|
|
|
$resultArray[] = $value; |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
return $resultArray; |
960
|
|
|
}, |
961
|
|
|
array() |
962
|
|
|
); |
963
|
|
|
|
964
|
|
|
return self::create($this->array); |
965
|
|
|
} |
966
|
|
|
} |
967
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.