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.

Arrays::toCellArray()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

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