Code

< 40 %
40-60 %
> 60 %
1
<?php
2
/**
3
 * Collection library for PHP.
4
 *
5
 * @link      https://github.com/hiqdev/php-collection
6
 * @package   php-collection
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\collection;
12
13
/**
14
 * Array Helper.
15
 *
16
 * @author Andrii Vasyliev <[email protected]>
17
 */
18
class ArrayHelper
19
{
20
    /**
21
     * Recursive safe merge.
22
     * Based on Yii2 yii\helpers\BaseArrayHelper::merge.
23
     *
24
     * Merges two or more arrays into one recursively.
25
     * If each array has an element with the same string key value, the latter
26
     * will overwrite the former (different from array_merge_recursive).
27
     * Recursive merging will be conducted if both arrays have an element of array
28
     * type and are having the same key.
29
     * For integer-keyed elements, the elements from the latter array will
30
     * be appended to the former array.
31
     *
32
     * @param array $a array to be merged to
33
     * @param array $b array to be merged from
34
     * @return array the merged array
35
     */
36 1
    public static function merge($a, $b)
37
    {
38 1
        $args = func_get_args();
39 1
        $res = array_shift($args);
40 1
        foreach ($args as $items) {
41 1
            if (!is_array($items)) {
42
                continue;
43
            }
44 1
            foreach ($items as $k => $v) {
45 1
                if (is_int($k)) {
46 1
                    if (isset($res[$k])) {
47 1
                        $res[] = $v;
48
                    } else {
49 1
                        $res[$k] = $v;
50
                    }
51 1
                } elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
52 1
                    $res[$k] = self::merge($res[$k], $v);
53
                } else {
54 1
                    $res[$k] = $v;
55
                }
56
            }
57
        }
58
59 1
        return $res;
60
    }
61
62
    /**
63
     * Get specified items as array.
64
     * @param mixed $keys specification
65
     * @return array
66
     */
67 3
    public static function getItems($array, $keys = null)
68
    {
69 3
        if (is_null($keys)) {
70 2
            return $array;
71 1
        } elseif (is_scalar($keys)) {
72 1
            $keys = [$keys => $array[$keys]];
73
        }
74 1
        $res = [];
75 1
        foreach ($keys as $k) {
76 1
            if (array_key_exists($k, $array)) {
77 1
                $res[$k] = $array[$k];
78
            }
79
        }
80
        return $res;
81 1
    }
82
83
    /**
84
     * Inserts items in front of array.
85
     * rough method: unset and then set, think of better.
86
     */
87
    public static function insertLast(array $array, array $items)
88 2
    {
89
        foreach ($items as $k => $v) {
90 2
            unset($array[$k]);
91 2
        }
92
        foreach ($items as $k => $v) {
93 2
            $array[$k] = $v;
94 2
        }
95
96
        return $array;
97 2
    }
98
99
    /**
100
     * Inserts items in front of array.
101
     * rough method: unset and then set, think of better.
102
     */
103
    public static function insertFirst(array $array, array $items)
104 2
    {
105
        foreach (array_keys($items) as $k) {
106 2
            unset($array[$k]);
107 2
        }
108
        $array = array_merge($items, $array);
109 2
110
        return $array;
111 2
    }
112
113
    /**
114
     * Inserts items inside of array.
115
     * rough method: unset and then set, think of better.
116
     * @param array        $array source array
117
     * @param array        $items array of items
118
     * @param string|array $where where to insert
119
     * @return array new items list
120
     * @see add()
121
     */
122
    public static function insertInside(array $array, $items, $where)
123 1
    {
124
        foreach ($items as $k => $v) {
125 1
            unset($array[$k]);
126 1
        }
127
        $before = self::prepareWhere($array, isset($where['before']) ? $where['before'] : null);
128 1
        $after  = self::prepareWhere($array, isset($where['after']) ? $where['after'] : null);
129 1
        $new    = [];
130 1
        $found  = false;
131 1
        /// TODO think of realizing it better
132
        foreach ($array as $k => $v) {
133 1
            if (!$found && $k === $before) {
134 1
                foreach ($items as $i => $c) {
135 1
                    $new[$i] = $c;
136 1
                }
137
                $found = true;
138 1
            }
139
            $new[$k] = $v;
140 1
            if (!$found && $k === $after) {
141 1
                foreach ($items as $i => $c) {
142 1
                    $new[$i] = $c;
143 1
                }
144
                $found = true;
145 1
            }
146
        }
147
        if (!$found) {
148 1
            foreach ($items as $i => $c) {
149 1
                $new[$i] = $c;
150 1
            }
151
        }
152
153
        return $new;
154 1
    }
155
156
    /**
157
     * Internal function to prepare where list for insertInside.
158
     * @param array        $array source array
159
     * @param array|string $list  array to convert
160
     * @return array
161
     */
162
    protected static function prepareWhere(array $array, $list)
163 1
    {
164
        if (!is_array($list)) {
165 1
            $list = [$list];
166 1
        }
167
        foreach ($list as $v) {
168 1
            if (array_key_exists($v, $array)) {
169 1
                return $v;
170 1
            }
171
        }
172
173
        return null;
174 1
    }
175
176
    /**
177
     * Recursively removes duplicate values from non-associative arrays.
178
     */
179
    public static function unique($array)
180 1
    {
181
        $suitable = true;
182 1
        foreach ($array as $k => &$v) {
183 1
            if (is_array($v)) {
184 1
                $v = self::unique($v);
185 1
            } elseif (!is_int($k)) {
186 1
                $suitable = false;
187 1
            }
188
        }
189
190
        return $suitable ? self::uniqueFlat($array) : $array;
191 1
    }
192
193
    /**
194
     * Non-recursively removes duplicate values from non-associative arrays.
195
     */
196
    public static function uniqueFlat($array)
197 2
    {
198
        $uniqs = [];
199 2
        $res = [];
200 2
        foreach ($array as $k => $v) {
201 2
            $uv = var_export($v, true);
202 2
            if (array_key_exists($uv, $uniqs)) {
203 2
                continue;
204 2
            }
205
            $uniqs[$uv] = 1;
206 2
            $res[$k] = $v;
207 2
        }
208
209
        return $res;
210 2
    }
211
212
    public static function toArray($object)
213 1
    {
214
        $res = (array) $object;
215 1
        foreach ($res as &$v) {
216 1
            if (is_object($v)) {
217 1
                $v = self::toArray($v);
218 1
            }
219
        }
220
221
        return $res;
222 1
    }
223
}
224