Arr.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. <?php
  2. /*
  3. * This file is part of the overtrue/wechat.
  4. *
  5. * (c) overtrue <i@overtrue.me>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. /**
  11. * Arr.php.
  12. *
  13. * @author overtrue <i@overtrue.me>
  14. * @copyright 2015 overtrue <i@overtrue.me>
  15. *
  16. * @see https://github.com/overtrue
  17. * @see http://overtrue.me
  18. * @see https://github.com/laravel/framework/blob/4.2/src/Illuminate/Support/Arr.php
  19. */
  20. namespace EasyWeChat\Support;
  21. use Closure;
  22. /**
  23. * Array helper from Illuminate\Support\Arr.
  24. */
  25. class Arr
  26. {
  27. /**
  28. * Add an element to an array using "dot" notation if it doesn't exist.
  29. *
  30. * @param array $array
  31. * @param string $key
  32. * @param mixed $value
  33. *
  34. * @return array
  35. */
  36. public static function add($array, $key, $value)
  37. {
  38. if (is_null(static::get($array, $key))) {
  39. static::set($array, $key, $value);
  40. }
  41. return $array;
  42. }
  43. /**
  44. * Build a new array using a callback.
  45. *
  46. * @param array $array
  47. * @param \Closure $callback
  48. *
  49. * @return array
  50. */
  51. public static function build($array, Closure $callback)
  52. {
  53. $results = [];
  54. foreach ($array as $key => $value) {
  55. list($innerKey, $innerValue) = call_user_func($callback, $key, $value);
  56. $results[$innerKey] = $innerValue;
  57. }
  58. return $results;
  59. }
  60. /**
  61. * Divide an array into two arrays. One with keys and the other with values.
  62. *
  63. * @param array $array
  64. *
  65. * @return array
  66. */
  67. public static function divide($array)
  68. {
  69. return [
  70. array_keys($array),
  71. array_values($array),
  72. ];
  73. }
  74. /**
  75. * Flatten a multi-dimensional associative array with dots.
  76. *
  77. * @param array $array
  78. * @param string $prepend
  79. *
  80. * @return array
  81. */
  82. public static function dot($array, $prepend = '')
  83. {
  84. $results = [];
  85. foreach ($array as $key => $value) {
  86. if (is_array($value)) {
  87. $results = array_merge($results, static::dot($value, $prepend.$key.'.'));
  88. } else {
  89. $results[$prepend.$key] = $value;
  90. }
  91. }
  92. return $results;
  93. }
  94. /**
  95. * Get all of the given array except for a specified array of items.
  96. *
  97. * @param array $array
  98. * @param array|string $keys
  99. *
  100. * @return array
  101. */
  102. public static function except($array, $keys)
  103. {
  104. return array_diff_key($array, array_flip((array) $keys));
  105. }
  106. /**
  107. * Fetch a flattened array of a nested array element.
  108. *
  109. * @param array $array
  110. * @param string $key
  111. *
  112. * @return array
  113. */
  114. public static function fetch($array, $key)
  115. {
  116. $results = [];
  117. foreach (explode('.', $key) as $segment) {
  118. $results = [];
  119. foreach ($array as $value) {
  120. $value = (array) $value;
  121. $results[] = $value[$segment];
  122. }
  123. $array = array_values($results);
  124. }
  125. return array_values($results);
  126. }
  127. /**
  128. * Return the first element in an array passing a given truth test.
  129. *
  130. * @param array $array
  131. * @param \Closure $callback
  132. * @param mixed $default
  133. *
  134. * @return mixed
  135. */
  136. public static function first($array, $callback, $default = null)
  137. {
  138. foreach ($array as $key => $value) {
  139. if (call_user_func($callback, $key, $value)) {
  140. return $value;
  141. }
  142. }
  143. return $default;
  144. }
  145. /**
  146. * Return the last element in an array passing a given truth test.
  147. *
  148. * @param array $array
  149. * @param \Closure $callback
  150. * @param mixed $default
  151. *
  152. * @return mixed
  153. */
  154. public static function last($array, $callback, $default = null)
  155. {
  156. return static::first(array_reverse($array), $callback, $default);
  157. }
  158. /**
  159. * Flatten a multi-dimensional array into a single level.
  160. *
  161. * @param array $array
  162. *
  163. * @return array
  164. */
  165. public static function flatten($array)
  166. {
  167. $return = [];
  168. array_walk_recursive(
  169. $array,
  170. function ($x) use (&$return) {
  171. $return[] = $x;
  172. }
  173. );
  174. return $return;
  175. }
  176. /**
  177. * Remove one or many array items from a given array using "dot" notation.
  178. *
  179. * @param array $array
  180. * @param array|string $keys
  181. */
  182. public static function forget(&$array, $keys)
  183. {
  184. $original = &$array;
  185. foreach ((array) $keys as $key) {
  186. $parts = explode('.', $key);
  187. while (count($parts) > 1) {
  188. $part = array_shift($parts);
  189. if (isset($array[$part]) && is_array($array[$part])) {
  190. $array = &$array[$part];
  191. }
  192. }
  193. unset($array[array_shift($parts)]);
  194. // clean up after each pass
  195. $array = &$original;
  196. }
  197. }
  198. /**
  199. * Get an item from an array using "dot" notation.
  200. *
  201. * @param array $array
  202. * @param string $key
  203. * @param mixed $default
  204. *
  205. * @return mixed
  206. */
  207. public static function get($array, $key, $default = null)
  208. {
  209. if (is_null($key)) {
  210. return $array;
  211. }
  212. if (isset($array[$key])) {
  213. return $array[$key];
  214. }
  215. foreach (explode('.', $key) as $segment) {
  216. if (!is_array($array) || !array_key_exists($segment, $array)) {
  217. return $default;
  218. }
  219. $array = $array[$segment];
  220. }
  221. return $array;
  222. }
  223. /**
  224. * Get a subset of the items from the given array.
  225. *
  226. * @param array $array
  227. * @param array|string $keys
  228. *
  229. * @return array
  230. */
  231. public static function only($array, $keys)
  232. {
  233. return array_intersect_key($array, array_flip((array) $keys));
  234. }
  235. /**
  236. * Pluck an array of values from an array.
  237. *
  238. * @param array $array
  239. * @param string $value
  240. * @param string $key
  241. *
  242. * @return array
  243. */
  244. public static function pluck($array, $value, $key = null)
  245. {
  246. $results = [];
  247. foreach ($array as $item) {
  248. $itemValue = is_object($item) ? $item->{$value} : $item[$value];
  249. // If the key is "null", we will just append the value to the array and keep
  250. // looping. Otherwise we will key the array using the value of the key we
  251. // received from the developer. Then we'll return the final array form.
  252. if (is_null($key)) {
  253. $results[] = $itemValue;
  254. } else {
  255. $itemKey = is_object($item) ? $item->{$key} : $item[$key];
  256. $results[$itemKey] = $itemValue;
  257. }
  258. }
  259. return $results;
  260. }
  261. /**
  262. * Get a value from the array, and remove it.
  263. *
  264. * @param array $array
  265. * @param string $key
  266. * @param mixed $default
  267. *
  268. * @return mixed
  269. */
  270. public static function pull(&$array, $key, $default = null)
  271. {
  272. $value = static::get($array, $key, $default);
  273. static::forget($array, $key);
  274. return $value;
  275. }
  276. /**
  277. * Set an array item to a given value using "dot" notation.
  278. *
  279. * If no key is given to the method, the entire array will be replaced.
  280. *
  281. * @param array $array
  282. * @param string $key
  283. * @param mixed $value
  284. *
  285. * @return array
  286. */
  287. public static function set(&$array, $key, $value)
  288. {
  289. if (is_null($key)) {
  290. return $array = $value;
  291. }
  292. $keys = explode('.', $key);
  293. while (count($keys) > 1) {
  294. $key = array_shift($keys);
  295. // If the key doesn't exist at this depth, we will just create an empty array
  296. // to hold the next value, allowing us to create the arrays to hold final
  297. // values at the correct depth. Then we'll keep digging into the array.
  298. if (!isset($array[$key]) || !is_array($array[$key])) {
  299. $array[$key] = [];
  300. }
  301. $array = &$array[$key];
  302. }
  303. $array[array_shift($keys)] = $value;
  304. return $array;
  305. }
  306. /**
  307. * Sort the array using the given Closure.
  308. *
  309. * @param array $array
  310. * @param \Closure $callback
  311. *
  312. * @return array
  313. */
  314. public static function sort($array, Closure $callback)
  315. {
  316. $results = [];
  317. foreach ($array as $key => $value) {
  318. $results[$key] = $callback($value);
  319. }
  320. return $results;
  321. }
  322. /**
  323. * Filter the array using the given Closure.
  324. *
  325. * @param array $array
  326. * @param \Closure $callback
  327. *
  328. * @return array
  329. */
  330. public static function where($array, Closure $callback)
  331. {
  332. $filtered = [];
  333. foreach ($array as $key => $value) {
  334. if (call_user_func($callback, $key, $value)) {
  335. $filtered[$key] = $value;
  336. }
  337. }
  338. return $filtered;
  339. }
  340. }