GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#23)
by t
03:07
created

Arrays::explode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 8
ccs 0
cts 6
cp 0
crap 6
rs 10
1
<?php
2
/**
3
 * Class Arrays
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2017, icy2003
8
 */
9
10
namespace icy2003\php\ihelpers;
11
12
use icy2003\php\C;
13
use icy2003\php\I;
14
15
/**
16
 * 数组类
17
 *
18
 * 常见数组格式的拼装和处理
19
 *
20
 * @test icy2003\php_tests\ihelpers\ArraysTest
21
 */
22
class Arrays
23
{
24
25
    /**
26
     * 以各个元素的某字段值作为键重新指回该元素,此值对于该元素需唯一
27
     *
28
     * @param array  $array 元素可以为数组或者对象
29
     * @param string $index 用来作为键的某字段,不能为 null
30
     * @param boolean $isMerge 是否合并相同键的项到数组,默认否(也就是后者覆盖前者)
31
     *
32
     * @return array
33
     *
34
     * @tested
35
     */
36 1
    public static function indexBy($array, $index, $isMerge = false)
37
    {
38 1
        $result = [];
39 1
        foreach ($array as $row) {
40 1
            $indexValue = I::get($row, $index);
41 1
            if (null === $indexValue) {
42 1
                return [];
43
            }
44 1
            if (false === $isMerge) {
45 1
                $result[$indexValue] = $row;
46
            } else {
47 1
                $result[$indexValue][] = $row;
48
            }
49
        }
50
51 1
        return $result;
52
    }
53
54
    /**
55
     * 选取数组中指定键的某几列
56
     *
57
     * - 简单理解就是:从数据库里查出来几条数据,只拿其中的几个属性
58
     * - 当 $dimension 为 2 时,理解为从几条数据里拿属性
59
     * - 当 $dimension 为 1 时,理解为从一条数据里拿属性
60
     *
61
     * @param array $array
62
     * @param array $keys 某几项字段,支持 I::get 的键格式,如果是键值对,键会被设置为键
63
     *      - [a, b]:查找 a 和 b
64
     *      - [a.b, c]:查找 a.b 和 c
65
     *      - [a => b]:查找 b 并且设置该项的键为 a
66
     * @param integer $dimension 维度,只能为 1 或 2,默认 2,表示处理二维数组
67
     *
68
     * @return array
69
     *
70
     * @tested
71
     */
72 1
    public static function columns($array, $keys = null, $dimension = 2)
73
    {
74 1
        if (null === $keys) {
75 1
            return $array;
76
        }
77 1
        $result = [];
78 1
        if (2 === $dimension) {
79 1
            foreach ($array as $k => $row) {
80 1
                foreach ($keys as $k1 => $key) {
81 1
                    $value = I::get($row, $key);
82 1
                    if (is_numeric($k1)) {
83 1
                        $result[$k][$key] = $value;
84
                    } else {
85
                        $result[$k][$k1] = $value;
86
                    }
87
                }
88
            }
89
        }
90 1
        if (1 === $dimension) {
91 1
            foreach ($keys as $k1 => $key) {
92 1
                $value = I::get($array, $key);
93 1
                if (is_numeric($k1)) {
94 1
                    $result[$key] = $value;
95
                } else {
96
                    $result[$k1] = $value;
97
                }
98
            }
99
        }
100
101 1
        return $result;
102
    }
103
104
    /**
105
     * 返回二维(或者更高)数组中指定键的一列的所有值
106
     *
107
     * - array_column 要求 PHP >= 5.5,这个是兼容 5.5 以下的
108
     * - 如果需要取某几项,使用 Arrays::columns
109
     * - 简单理解就是:从数据库里查出来几条数据,只要其中某个属性的所有值
110
     * - USE_CUSTOM
111
     *
112
     * @see http://php.net/array_column
113
     *
114
     * @param array $array
115
     * @param string $column 需要被取出来的字段
116
     * @param string $index 作为 index 的字段
117
     *
118
     * @return array
119
     *
120
     * @tested
121
     */
122 2
    public static function column($array, $column, $index = null)
123
    {
124 2
        if (function_exists('array_column') && false === I::ini('USE_CUSTOM')) {
125 2
            return array_column($array, $column, $index);
126
        } else {
127 1
            $result = [];
128 1
            foreach ($array as $row) {
129 1
                $data = I::get($row, $column);
130 1
                if (null === $index) {
131 1
                    $result[] = $data;
132
                } else {
133 1
                    $result[$row[$index]] = $data;
134
                }
135
            }
136
137 1
            return $result;
138
        }
139
    }
140
141
    /**
142
     * 创建一个数组,用一个数组的值作为其键名,另一个数组的值作为其值
143
     *
144
     * - array_combine:两个数组元素个数不一致将报错
145
     * - 在两个数组元素个数不一致时,以键为准:
146
     *      1.键比值多,值都被填充为 null
147
     *      2.值比键多,值被舍去
148
     * ```
149
     *
150
     * @see http://php.net/array_combine
151
     *
152
     * @param array $keys
153
     * @param array $values
154
     *
155
     * @return array
156
     *
157
     * @tested
158
     */
159 2
    public static function combine($keys, $values)
160
    {
161 2
        if (count($keys) == count($values)) {
162 2
            return (array)array_combine($keys, $values);
163
        }
164 1
        $array = [];
165 1
        foreach ($keys as $index => $key) {
166 1
            $array[$key] = I::get($values, $index);
167
        }
168 1
        return $array;
169
    }
170
171
    /**
172
     * 递归地合并多个数组
173
     *
174
     * - array_merge_recursive:如果有相同的键,后者会覆盖前者
175
     * - 此函数会合并两个相同键的值到一个数组里
176
     *
177
     * @see http://php.net/array_merge_recursive
178
     *
179
     * @param array $a 数组1
180
     * @param array $b 数组2(可以任意个数组)
181
     *
182
     * @return array
183
     *
184
     * @tested
185
     */
186 38
    public static function merge($a, $b)
187
    {
188 38
        $args = func_get_args();
189 38
        $res = array_shift($args);
190 38
        while (!empty($args)) {
191 38
            foreach (array_shift($args) as $k => $v) {
192 3
                if (is_int($k)) {
193 2
                    if (array_key_exists($k, $res)) {
194 2
                        $res[] = $v;
195
                    } else {
196 2
                        $res[$k] = $v;
197
                    }
198 2
                } elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
199 1
                    $res[$k] = self::merge($res[$k], $v);
200
                } else {
201 2
                    $res[$k] = $v;
202
                }
203
            }
204
        }
205
206 38
        return $res;
207
    }
208
209
    /**
210
     *  range 的性能优化版
211
     *
212
     * @see http://php.net/manual/zh/language.generators.overview.php
213
     * @version PHP >= 5.5
214
     *
215
     * @param integer $start 开始
216
     * @param integer $end 结束
217
     * @param integer $step 步长
218
     *
219
     * @return \Generator
220
     *
221
     * @tested
222
     */
223 8
    public static function rangeGenerator($start, $end, $step = 1)
224
    {
225 8
        if ($start < $end) {
226 7
            C::assertTrue($step > 0, '步长必须大于 0');
227 7
            for ($i = $start; $i <= $end; $i += $step) {
228 7
                yield $i;
229
            }
230 3
        } elseif ($start > $end) {
231 1
            C::assertTrue($step < 0, '步长必须小于 0');
232 1
            for ($i = $start; $i >= $end; $i += $step) {
233 1
                yield $i;
234
            }
235
        } else {
236 2
            yield $start;
237
        }
238 8
    }
239
240
    /**
241
     * 找到符合条件的第一项
242
     *
243
     * @param array $array
244
     * @param callback $callback 条件回调,结果为 true 的第一项会被取出
245
     *
246
     * @return mixed
247
     *
248
     * @tested
249
     */
250 1
    public static function detectFirst($array, $callback)
251
    {
252 1
        foreach ($array as $key => $item) {
253 1
            if (true === I::call($callback, [$item, $key])) {
254 1
                return $item;
255
            }
256
        }
257 1
        return null;
258
    }
259
260
    /**
261
     * 找到符合条件的所有项
262
     *
263
     * @param array $array
264
     * @param callback $callback 条件回调,结果为 true 的所有项会被取出
265
     * @param callback $filter 对符合条件的项进行回调处理并返回
266
     *
267
     * @return array
268
     *
269
     * @tested
270
     */
271 1
    public static function detectAll($array, $callback, $filter = null)
272
    {
273 1
        $all = [];
274 1
        foreach ($array as $key => $item) {
275 1
            if (true === I::call($callback, [$item, $key])) {
276 1
                if (null !== $filter) {
277 1
                    $all[$key] = I::call($filter, [$item, $key]);
278
                } else {
279 1
                    $all[$key] = $item;
280
                }
281
            }
282
        }
283 1
        return $all;
284
    }
285
286
    /**
287
     * 返回数组的最后一个元素的键
288
     *
289
     * - array_key_last:需要 PHP7.3.0+ 才能支持
290
     * - USE_CUSTOM
291
     *
292
     * @param array $array
293
     *
294
     * @return string|null
295
     *
296
     * @tested
297
     */
298 1
    public static function keyLast($array)
299
    {
300 1
        if (!is_array($array) || empty($array)) {
301 1
            return null;
302
        }
303 1
        if (function_exists('array_key_last') && false === I::ini('USE_CUSTOM')) {
304 1
            return array_key_last($array);
305
        }
306 1
        end($array);
307 1
        return key($array);
308
    }
309
310
    /**
311
     * 返回数组的第一个元素的键
312
     *
313
     * - array_key_first:需要 PHP7.3.0+ 才能支持
314
     * - USE_CUSTOM
315
     *
316
     * @param array $array
317
     *
318
     * @return string|null
319
     *
320
     * @tested
321
     */
322 1
    public static function keyFirst($array)
323
    {
324 1
        if (!is_array($array) || empty($array)) {
325 1
            return null;
326
        }
327 1
        if (function_exists('array_key_first') && false === I::ini('USE_CUSTOM')) {
328 1
            return array_key_first($array);
329
        }
330 1
        reset($array);
331 1
        return key($array);
332
    }
333
334
    /**
335
     * 获取数组的维度
336
     *
337
     * @param array $array 多维数组
338
     *
339
     * @return integer
340
     *
341
     * @tested
342
     */
343 1
    public static function dimension($array)
344
    {
345 1
        if (!is_array($array)) {
346 1
            return 0;
347
        }
348 1
        $max = 1;
349 1
        foreach ($array as $value) {
350 1
            if (is_array($value)) {
351 1
                $d = self::dimension($value) + 1;
352 1
                if ($d > $max) {
353 1
                    $max = $d;
354
                }
355
            }
356
        }
357 1
        return $max;
358
    }
359
360
    /**
361
     * 判断数组是不是关联数组
362
     *
363
     * @param array $array
364
     *
365
     * @return boolean
366
     *
367
     * @tested
368
     */
369 1
    public static function isAssoc($array)
370
    {
371 1
        if (is_array($array)) {
372 1
            $keys = array_keys($array);
373 1
            return $keys !== array_keys($keys);
374
        }
375 1
        return false;
376
    }
377
378
    /**
379
     * 判断数组是不是索引数组
380
     *
381
     * 索引数组必须是下标从 0 开始的数组,键是数字还是字符串类型的数字无所谓
382
     *
383
     * @param array $array
384
     *
385
     * @return boolean
386
     *
387
     * @tested
388
     */
389 1
    public static function isIndexed($array)
390
    {
391 1
        if (is_array($array)) {
392 1
            $keys = array_keys($array);
393 1
            return $keys === array_keys($keys);
394
        }
395 1
        return false;
396
    }
397
398
    /**
399
     * 返回数组的顺数第 n 个元素,其中 n >= 1 且为整数,空数组直接返回 null
400
     *
401
     * - 支持关联数组,超过数组长度会对数组长度求余后查找
402
     *
403
     * @param array $array
404
     * @param int $pos 顺数第 n 个,默认 1
405
     *
406
     * @return mixed
407
     *
408
     * @tested
409
     */
410 3
    public static function first($array, $pos = 1)
411
    {
412 3
        if (0 === ($count = self::count($array))) {
413 1
            return null;
414
        }
415 3
        $p = $pos % $count;
416 3
        if (0 === $p) {
417 2
            $p = $count;
418
        }
419 3
        for ($i = 1; $i < $p; $i++) {
420 1
            next($array);
421
        }
422 3
        return current($array);
423
    }
424
425
    /**
426
     * 返回数组的倒数第 n 个元素,其中 n >= 1 且为整数,空数组直接返回 null
427
     *
428
     * - 支持关联数组,超过数组长度会对数组长度求余后查找
429
     *
430
     * @param array $array
431
     * @param int $pos 倒数第 n 个,默认 1
432
     *
433
     * @return mixed
434
     *
435
     * @tested
436
     */
437 1
    public static function last($array, $pos = 1)
438
    {
439 1
        if (0 === ($count = self::count($array))) {
440 1
            return null;
441
        }
442 1
        $p = $pos % $count;
443 1
        if (0 === $p) {
444 1
            $p = $count;
445
        }
446 1
        end($array);
447 1
        for ($i = 1; $i < $p; $i++) {
448 1
            prev($array);
449
        }
450 1
        return current($array);
451
    }
452
453
    /**
454
     * 计算数组中的单元数目
455
     *
456
     * - count:在非数组情况下,除了 null 会返回 0,其他都返回 1,囧
457
     * - $callback 参数用于对符合条件的项做筛选
458
     *
459
     * @param array|mixed $array 数组
460
     * @param callback|mixed $callback 回调,返回回调值为 true 的项,如果此参数是非回调类型,表示查询和此值严格相等的项
461
     * @param boolean $isStrict 是否为严格模式,如果为 false,回调值为 true 值的也会返回,为字符串时不使用严格比较
462
     *
463
     * @return integer
464
     *
465
     * @tested
466
     */
467 10
    public static function count($array, $callback = null, $isStrict = true)
468
    {
469 10
        $count = 0;
470 10
        if (is_array($array)) {
471 10
            if (null === $callback) {
472 10
                return count($array);
473
            } else {
474 2
                $function = $callback;
475 2
                if (false === is_callable($callback)) {
476
                    $function = function($row) use ($callback, $isStrict) {
477 2
                        return true === $isStrict ? $row === $callback : $row == $callback;
478 2
                    };
479
                }
480 2
                foreach ($array as $key => $row) {
481 2
                    if (true === I::call($function, [$row, $key])) {
482 2
                        $count++;
483
                    }
484
                }
485
486
            }
487
        }
488 2
        return $count;
489
    }
490
491
    /**
492
     * 返回指定长度的数组,不足的值设置为 null
493
     *
494
     * @param array $array
495
     * @param integer $count 指定长度
496
     * @param callback $callback 回调参数:数组的值、数组的键
497
     *
498
     * @return array
499
     *
500
     * @tested
501
     */
502 2
    public static function lists($array, $count = null, $callback = null)
503
    {
504 2
        null === $count && $count = self::count($array);
505 2
        $arrayCount = self::count($array);
506 2
        if ($arrayCount >= $count) {
507 2
            $return = $array;
508
        } else {
509 1
            $return = self::merge($array, self::fill(0, $count - $arrayCount, null));
510
        }
511 2
        if (null !== $callback) {
512 1
            foreach ($return as $key => $value) {
513 1
                $return[$key] = I::call($callback, [$value, $key]);
514
            }
515
        }
516 2
        return $return;
517
    }
518
519
    /**
520
     * 获取指定某些键的项的值
521
     *
522
     * @param array $array
523
     * @param array|string $keys 数组或逗号字符串
524
     *
525
     * @return array
526
     *
527
     * @tested
528
     */
529 1
    public static function values($array, $keys = null)
530
    {
531 1
        return array_values(self::some($array, $keys));
532
    }
533
534
    /**
535
     * 获取指定某些键的项
536
     *
537
     * @param array $array
538
     * @param array|string $keys 数组或都好字符串
539
     *
540
     * @return array
541
     *
542
     * @tested
543
     */
544 2
    public static function some($array, $keys = null)
545
    {
546 2
        if (null === $keys) {
547 1
            return $array;
548
        }
549 2
        $keys = Strings::toArray($keys);
550 2
        return array_intersect_key($array, array_flip($keys));
551
    }
552
553
    /**
554
     * 获取指定除了某些键的项
555
     *
556
     * @param array $array
557
     * @param array|string $keys
558
     *
559
     * @return array
560
     *
561
     * @tested
562
     */
563 1
    public static function exceptedKeys($array, $keys)
564
    {
565 1
        $keys = Strings::toArray($keys);
566 1
        return array_diff_key($array, array_flip($keys));
567
    }
568
569
    /**
570
     * 检查数组里是否有指定的所有键名或索引
571
     *
572
     * - array_key_exists:检测一个指定的键
573
     * - Arrays::keyExistsOne:检测数组里是否存在指定的某些键
574
     *
575
     * @param array $keys 要检查的键
576
     * @param array $array
577
     * @param array $diff 引用返回不包含的键
578
     *
579
     * @return boolean
580
     *
581
     * @tested
582
     */
583 1
    public static function keyExistsAll($keys, $array, &$diff = null)
584
    {
585
586 1
        return I::isEmpty($diff = array_diff($keys, array_keys($array)));
587
    }
588
589
    /**
590
     * 检查数组里是否有指定的某些键名或索引
591
     *
592
     * @param array $keys 要检查的键
593
     * @param array $array
594
     * @param array $find 引用返回包含的键
595
     *
596
     * @return boolean
597
     *
598
     * @tested
599
     */
600 1
    public static function keyExistsSome($keys, $array, &$find = null)
601
    {
602 1
        return !I::isEmpty($find = array_intersect($keys, array_keys($array)));
603
    }
604
605
    /**
606
     * 检查数组里是否有指定的所有值
607
     *
608
     * @param array $values 要检查的值
609
     * @param array $array
610
     * @param array $diff 引用返回不包含的值
611
     *
612
     * @return boolean
613
     *
614
     * @tested
615
     */
616 1
    public static function valueExistsAll($values, $array, &$diff = null)
617
    {
618 1
        return I::isEmpty($diff = array_diff($values, array_values($array)));
619
    }
620
621
    /**
622
     * 检查数组里是否有指定的某些值
623
     *
624
     * @param array $values 要检查的值
625
     * @param array $array
626
     * @param array $find 引用返回包含的值
627
     *
628
     * @return boolean
629
     *
630
     * @tested
631
     */
632 1
    public static function valueExistsSome($values, $array, &$find = null)
633
    {
634 1
        return !I::isEmpty($find = array_intersect($values, array_values($array)));
635
    }
636
637
    /**
638
     * 参照 PHP 的 array_combine 函数,array_combine 得到的是一行记录的格式,该函数得到多行
639
     *
640
     * - arrays 里的每个数组会和 keys 使用 self::combine 合并,最终合并成为一个二维数组
641
     *
642
     * @param array $keys 作为键的字段
643
     * @param array $arrays
644
     *
645
     * @return array
646
     *
647
     * @tested
648
     */
649 1
    public static function combines($keys, $arrays)
650
    {
651 1
        $result = [];
652 1
        foreach ($arrays as $k => $array) {
653 1
            $result[$k] = self::combine($keys, $array);
654
        }
655
656 1
        return $result;
657
    }
658
659
    /**
660
     * 把数组里逗号字符串拆分,并且去掉重复的部分
661
     *
662
     * @param array $array
663
     *
664
     * @return array
665
     *
666
     * @tested
667
     */
668 2
    public static function toPart($array)
669
    {
670 2
        return array_values(
671 2
            array_filter(
672 2
                array_keys(
673 2
                    array_flip(
674 2
                        explode(',', implode(',', $array))
675
                    )
676
                )
677
            )
678
        );
679
    }
680
681
    /**
682
     * 矩阵转置
683
     *
684
     * @param array $array 待转置的矩阵
685
     *
686
     * @return array
687
     *
688
     * @tested
689
     */
690 1
    public static function transposed($array)
691
    {
692 1
        $data = [];
693 1
        foreach ($array as $r => $row) {
694 1
            foreach ($row as $c => $col) {
695 1
                $data[$c][$r] = $col;
696
            }
697
        }
698 1
        return $data;
699
    }
700
701
    /**
702
     * 普通二维数组转化成 Excel 单元格二维数组
703
     *
704
     * @param array $array
705
     *
706
     * @return array
707
     *
708
     * @tested
709
     */
710 1
    public static function toCellArray($array)
711
    {
712 1
        $data = [];
713 1
        $rowIndex = 0;
714 1
        foreach ($array as $row) {
715 1
            $rowIndex++;
716 1
            $colIndex = 'A';
717 1
            foreach ($row as $col) {
718 1
                $data[$rowIndex][$colIndex++] = $col;
719
            }
720
        }
721 1
        return $data;
722
    }
723
724
    /**
725
     * 返回矩阵的列数和行数
726
     *
727
     * - 返回两个元素的一维数组,第一个元素表示矩阵的列数,第二个元素表示矩阵的行数
728
     *
729
     * @param array $array
730
     *
731
     * @return array
732
     *
733
     * @tested
734
     */
735 2
    public static function colRowCount($array)
736
    {
737 2
        return [self::count(self::first($array)), self::count($array)];
738
    }
739
740
    /**
741
     * 用给定的值填充数组
742
     *
743
     * - array_fill:第一参数在为负的时候,生成的数组的第二个元素是从 0 开始的!
744
     *
745
     * @param int $startIndex 返回的数组的第一个索引值
746
     * @param int $num 插入元素的数量。如果为 0 或者负数,则返回空数组
747
     * @param mixed $value 用来填充的值
748
     *
749
     * @return array
750
     *
751
     * @tested
752
     */
753 2
    public static function fill($startIndex, $num, $value)
754
    {
755 2
        if ($num <= 0) {
756 1
            return [];
757
        }
758 2
        $array = [];
759 2
        foreach (self::rangeGenerator($startIndex, $startIndex + $num - 1) as $key) {
760 2
            $array[$key] = $value;
761
        }
762 2
        return $array;
763
    }
764
765
    /**
766
     * 让 var_export 返回 `[]` 的格式
767
     *
768
     * @param mixed $expression 变量
769
     * @param bool $return 默认值 为 true,即返回字符串而不是输出
770
     *
771
     * @return mixed
772
     *
773
     * @tested
774
     */
775 1
    public static function export($expression, $return = true)
776
    {
777 1
        $export = var_export($expression, true);
778 1
        $export = preg_replace("/^([ ]*)(.*)/m", '$1$1$2', $export);
779 1
        $array = preg_split("/\r\n|\n|\r/", $export);
780 1
        $array = preg_replace(["/\s*array\s\($/", "/\)(,)?$/", "/\s=>\s$/"], [null, ']$1', ' => ['], $array);
781 1
        $export = implode(PHP_EOL, array_filter(["["] + $array));
782 1
        if (true === $return) {
783 1
            return $export;
784
        } else {
785 1
            echo $export;
786
        }
787 1
    }
788
789
    /**
790
     * 将 CSV 文本转成数组
791
     *
792
     * @param string $csvString
793
     *
794
     * @return array
795
     *
796
     * @tested
797
     */
798 1
    public static function fromCsv($csvString)
799
    {
800 1
        $lines = explode(PHP_EOL, $csvString);
801 1
        $array = [];
802 1
        foreach ($lines as $line) {
803 1
            $array[] = explode(',', $line);
804
        }
805 1
        return $array;
806
    }
807
808
    /**
809
     * 在数组中搜索给定的值,如果成功则返回首个相应的键名
810
     *
811
     * - 第一参数如果不是回调函数,则此方法等同于 array_search
812
     * - 第一参数如果是回调函数,则找到的条件为:回调值为 true
813
     * - 第三参数如果是 false,则回调值只需要 true 值即可(例如:1)
814
     *
815
     * @param mixed|callback $search 搜索的值
816
     * @param array $array 这个数组
817
     * @param boolean $isStrict 是否检查完全相同的元素
818
     *
819
     * @return mixed|false
820
     *
821
     * @tested
822
     */
823 1
    public static function search($search, $array, $isStrict = false)
824
    {
825 1
        if (false === is_callable($search)) {
826 1
            return array_search($search, $array, $isStrict);
827
        }
828 1
        foreach ($array as $key => $row) {
829 1
            $result = I::call($search, [$row]);
830 1
            if ((true === $isStrict && true === $result) || (false === $isStrict && true == $result)) {
831 1
                return $key;
832
            }
833
        }
834 1
        return false;
835
    }
836
837
    /**
838
     * 递增数组的一个值并返回
839
     *
840
     * - 如果该值不存在,则默认为 0
841
     *
842
     * @param array $array 引用返回数组
843
     * @param string $key
844
     * @param integer $step 步长,默认 1
845
     *
846
     * @return double|integer
847
     *
848
     * @tested
849
     */
850 1
    public static function increment(&$array, $key, $step = 1)
851
    {
852 1
        $array[$key] = I::get($array, $key, 0) + $step;
853 1
        return $array[$key];
854
    }
855
856
    /**
857
     * 递减数组的一个值并返回
858
     *
859
     * - 如果该值不存在,则默认为 0
860
     *
861
     * @param array $array 引用返回数组
862
     * @param string $key
863
     * @param integer $step 步长,默认 1
864
     *
865
     * @return double|integer
866
     *
867
     * @tested
868
     */
869 1
    public static function decrement(&$array, $key, $step = 1)
870
    {
871 1
        $array[$key] = I::get($array, $key, 0) - $step;
872 1
        return $array[$key];
873
    }
874
875
    /**
876
     * in_array 的扩展
877
     *
878
     * @param mixed $value
879
     * @param array|mixed $array
880
     * @param boolean $isStrict 是否严格匹配,默认 false,即不严格
881
     * @param boolean $ignoreCase 是否忽略大小写,默认 false,不忽略
882
     *
883
     * @return boolean
884
     */
885 3
    public static function in($value, $array, $isStrict = false, $ignoreCase = false)
886
    {
887 3
        if (false === is_array($array)) {
888 1
            return false;
889
        }
890 3
        if (false === $ignoreCase) {
891 1
            return in_array($value, $array, $isStrict);
892
        } else {
893 3
            $value = Json::decode(strtolower(Json::encode($value)));
894 3
            $array = (array)Json::decode(strtolower(Json::encode($array)));
895 3
            return in_array($value, $array, $isStrict);
896
        }
897
    }
898
899
    /**
900
     * 对一个数组执行回调并返回新数组
901
     *
902
     * @param array|mixed $array
903
     * @param callback $valueCallback 对值的回调
904
     * @param callback|null $keyCallback 对键的回调
905
     *
906
     * @return array
907
     */
908
    public static function map($array, $valueCallback, $keyCallback = null)
909
    {
910
        $return = [];
911
        if (is_array($array)) {
912
            foreach ($array as $key => $value) {
913
                $callValue = I::call($valueCallback, [$value, $key]);
914
                $callKey = null === $keyCallback ? $key : I::call($keyCallback, [$value, $key]);
915
                $return[$callKey] = $callValue;
916
            }
917
        }
918
        return $return;
919
    }
920
921
    /**
922
     * 排队取号
923
     *
924
     * - 含义:给定只包含数字的索引数组,索引数组的值作为号码从小到大排序,如果中间漏掉某个号码,则返回该号码,否则返回最后一位号码,并且引用返回该队列
925
     * - 号码的值从 0 开始
926
     * - 例子:[4, 0, 1] 将引用返回数组[4, 0, 1, 2],函数返回 2
927
     *
928
     * @param array $array
929
     * @param integer $begin 开始的号码,默认为 0
930
     *
931
     * @return integer
932
     */
933
    public static function queueNumber(&$array, $begin = 0)
934
    {
935
        $array2 = $array;
936
        sort($array2);
937
        $next = $begin;
938
        foreach ($array2 as $v) {
939
            if ($v > $next) {
940
                break;
941
            } elseif ($v < $next) {
942
                if ($v + 1 > $next) {
943
                    $next = $v + 1;
944
                }
945
            } else {
946
                $next++;
947
            }
948
        }
949
        array_push($array, $next);
950
        return $next;
951
    }
952
953
    /**
954
     * 将一维数组的每项用分隔符拆分,得到两部分分别设置为新数组的键和值
955
     *
956
     * @param string $delimiter 分隔符
957
     * @param array $array
958
     *
959
     * @return array
960
     */
961
    public static function explode($delimiter, $array)
962
    {
963
        $return = [];
964
        foreach ($array as $row) {
965
            list($k, $v) = Arrays::lists(explode($delimiter, $row), 2);
966
            $return[$k] = $v;
967
        }
968
        return $return;
969
    }
970
971
}
972