1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Utils;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17:
18: class Arrays
19: {
20:
21: 22: 23:
24: final public function __construct()
25: {
26: throw new Nette\StaticClassException;
27: }
28:
29:
30: 31: 32: 33: 34: 35: 36: 37:
38: public static function get(array $arr, $key, $default = NULL)
39: {
40: foreach (is_array($key) ? $key : array($key) as $k) {
41: if (is_array($arr) && array_key_exists($k, $arr)) {
42: $arr = $arr[$k];
43: } else {
44: if (func_num_args() < 3) {
45: throw new Nette\InvalidArgumentException("Missing item '$k'.");
46: }
47: return $default;
48: }
49: }
50: return $arr;
51: }
52:
53:
54: 55: 56: 57: 58: 59: 60:
61: public static function & getRef(& $arr, $key)
62: {
63: foreach (is_array($key) ? $key : array($key) as $k) {
64: if (is_array($arr) || $arr === NULL) {
65: $arr = & $arr[$k];
66: } else {
67: throw new Nette\InvalidArgumentException('Traversed item is not an array.');
68: }
69: }
70: return $arr;
71: }
72:
73:
74: 75: 76: 77:
78: public static function mergeTree($arr1, $arr2)
79: {
80: $res = $arr1 + $arr2;
81: foreach (array_intersect_key($arr1, $arr2) as $k => $v) {
82: if (is_array($v) && is_array($arr2[$k])) {
83: $res[$k] = self::mergeTree($v, $arr2[$k]);
84: }
85: }
86: return $res;
87: }
88:
89:
90: 91: 92: 93:
94: public static function searchKey($arr, $key)
95: {
96: $foo = array($key => NULL);
97: return array_search(key($foo), array_keys($arr), TRUE);
98: }
99:
100:
101: 102: 103: 104:
105: public static function insertBefore(array & $arr, $key, array $inserted)
106: {
107: $offset = self::searchKey($arr, $key);
108: $arr = array_slice($arr, 0, $offset, TRUE) + $inserted + array_slice($arr, $offset, count($arr), TRUE);
109: }
110:
111:
112: 113: 114: 115:
116: public static function insertAfter(array & $arr, $key, array $inserted)
117: {
118: $offset = self::searchKey($arr, $key);
119: $offset = $offset === FALSE ? count($arr) : $offset + 1;
120: $arr = array_slice($arr, 0, $offset, TRUE) + $inserted + array_slice($arr, $offset, count($arr), TRUE);
121: }
122:
123:
124: 125: 126: 127:
128: public static function renameKey(array & $arr, $oldKey, $newKey)
129: {
130: $offset = self::searchKey($arr, $oldKey);
131: if ($offset !== FALSE) {
132: $keys = array_keys($arr);
133: $keys[$offset] = $newKey;
134: $arr = array_combine($keys, $arr);
135: }
136: }
137:
138:
139: 140: 141: 142:
143: public static function grep(array $arr, $pattern, $flags = 0)
144: {
145: return Strings::pcre('preg_grep', array($pattern, $arr, $flags));
146: }
147:
148:
149: 150: 151: 152:
153: public static function flatten(array $arr, $preserveKeys = FALSE)
154: {
155: $res = array();
156: $cb = $preserveKeys
157: ? function ($v, $k) use (& $res) { $res[$k] = $v; }
158: : function ($v) use (& $res) { $res[] = $v; };
159: array_walk_recursive($arr, $cb);
160: return $res;
161: }
162:
163:
164: 165: 166: 167:
168: public static function isList($value)
169: {
170: return is_array($value) && (!$value || array_keys($value) === range(0, count($value) - 1));
171: }
172:
173:
174: 175: 176: 177:
178: public static function associate(array $arr, $path)
179: {
180: $parts = is_array($path)
181: ? $path
182: : preg_split('#(\[\]|->|=|\|)#', $path, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
183:
184: if (!$parts || $parts[0] === '=' || $parts[0] === '|' || $parts === array('->')) {
185: throw new Nette\InvalidArgumentException("Invalid path '$path'.");
186: }
187:
188: $res = $parts[0] === '->' ? new \stdClass : array();
189:
190: foreach ($arr as $rowOrig) {
191: $row = (array) $rowOrig;
192: $x = & $res;
193:
194: for ($i = 0; $i < count($parts); $i++) {
195: $part = $parts[$i];
196: if ($part === '[]') {
197: $x = & $x[];
198:
199: } elseif ($part === '=') {
200: if (isset($parts[++$i])) {
201: $x = $row[$parts[$i]];
202: $row = NULL;
203: }
204:
205: } elseif ($part === '->') {
206: if (isset($parts[++$i])) {
207: $x = & $x->{$row[$parts[$i]]};
208: } else {
209: $row = is_object($rowOrig) ? $rowOrig : (object) $row;
210: }
211:
212: } elseif ($part !== '|') {
213: $x = & $x[(string) $row[$part]];
214: }
215: }
216:
217: if ($x === NULL) {
218: $x = $row;
219: }
220: }
221:
222: return $res;
223: }
224:
225: }
226: