annotate vendor/zendframework/zend-stdlib/src/ArrayUtils.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents c2387f117808
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@0 3 * Zend Framework (http://framework.zend.com/)
Chris@0 4 *
Chris@0 5 * @link http://github.com/zendframework/zf2 for the canonical source repository
Chris@0 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
Chris@0 7 * @license http://framework.zend.com/license/new-bsd New BSD License
Chris@0 8 */
Chris@0 9
Chris@0 10 namespace Zend\Stdlib;
Chris@0 11
Chris@0 12 use Traversable;
Chris@0 13 use Zend\Stdlib\ArrayUtils\MergeRemoveKey;
Chris@0 14 use Zend\Stdlib\ArrayUtils\MergeReplaceKeyInterface;
Chris@0 15
Chris@0 16 /**
Chris@0 17 * Utility class for testing and manipulation of PHP arrays.
Chris@0 18 *
Chris@0 19 * Declared abstract, as we have no need for instantiation.
Chris@0 20 */
Chris@0 21 abstract class ArrayUtils
Chris@0 22 {
Chris@0 23 /**
Chris@0 24 * Compatibility Flag for ArrayUtils::filter
Chris@0 25 */
Chris@0 26 const ARRAY_FILTER_USE_BOTH = 1;
Chris@0 27
Chris@0 28 /**
Chris@0 29 * Compatibility Flag for ArrayUtils::filter
Chris@0 30 */
Chris@0 31 const ARRAY_FILTER_USE_KEY = 2;
Chris@0 32
Chris@0 33 /**
Chris@0 34 * Test whether an array contains one or more string keys
Chris@0 35 *
Chris@0 36 * @param mixed $value
Chris@0 37 * @param bool $allowEmpty Should an empty array() return true
Chris@0 38 * @return bool
Chris@0 39 */
Chris@0 40 public static function hasStringKeys($value, $allowEmpty = false)
Chris@0 41 {
Chris@12 42 if (! is_array($value)) {
Chris@0 43 return false;
Chris@0 44 }
Chris@0 45
Chris@12 46 if (! $value) {
Chris@0 47 return $allowEmpty;
Chris@0 48 }
Chris@0 49
Chris@0 50 return count(array_filter(array_keys($value), 'is_string')) > 0;
Chris@0 51 }
Chris@0 52
Chris@0 53 /**
Chris@0 54 * Test whether an array contains one or more integer keys
Chris@0 55 *
Chris@0 56 * @param mixed $value
Chris@0 57 * @param bool $allowEmpty Should an empty array() return true
Chris@0 58 * @return bool
Chris@0 59 */
Chris@0 60 public static function hasIntegerKeys($value, $allowEmpty = false)
Chris@0 61 {
Chris@12 62 if (! is_array($value)) {
Chris@0 63 return false;
Chris@0 64 }
Chris@0 65
Chris@12 66 if (! $value) {
Chris@0 67 return $allowEmpty;
Chris@0 68 }
Chris@0 69
Chris@0 70 return count(array_filter(array_keys($value), 'is_int')) > 0;
Chris@0 71 }
Chris@0 72
Chris@0 73 /**
Chris@0 74 * Test whether an array contains one or more numeric keys.
Chris@0 75 *
Chris@0 76 * A numeric key can be one of the following:
Chris@0 77 * - an integer 1,
Chris@0 78 * - a string with a number '20'
Chris@0 79 * - a string with negative number: '-1000'
Chris@0 80 * - a float: 2.2120, -78.150999
Chris@0 81 * - a string with float: '4000.99999', '-10.10'
Chris@0 82 *
Chris@0 83 * @param mixed $value
Chris@0 84 * @param bool $allowEmpty Should an empty array() return true
Chris@0 85 * @return bool
Chris@0 86 */
Chris@0 87 public static function hasNumericKeys($value, $allowEmpty = false)
Chris@0 88 {
Chris@12 89 if (! is_array($value)) {
Chris@0 90 return false;
Chris@0 91 }
Chris@0 92
Chris@12 93 if (! $value) {
Chris@0 94 return $allowEmpty;
Chris@0 95 }
Chris@0 96
Chris@0 97 return count(array_filter(array_keys($value), 'is_numeric')) > 0;
Chris@0 98 }
Chris@0 99
Chris@0 100 /**
Chris@0 101 * Test whether an array is a list
Chris@0 102 *
Chris@0 103 * A list is a collection of values assigned to continuous integer keys
Chris@0 104 * starting at 0 and ending at count() - 1.
Chris@0 105 *
Chris@0 106 * For example:
Chris@0 107 * <code>
Chris@0 108 * $list = array('a', 'b', 'c', 'd');
Chris@0 109 * $list = array(
Chris@0 110 * 0 => 'foo',
Chris@0 111 * 1 => 'bar',
Chris@0 112 * 2 => array('foo' => 'baz'),
Chris@0 113 * );
Chris@0 114 * </code>
Chris@0 115 *
Chris@0 116 * @param mixed $value
Chris@0 117 * @param bool $allowEmpty Is an empty list a valid list?
Chris@0 118 * @return bool
Chris@0 119 */
Chris@0 120 public static function isList($value, $allowEmpty = false)
Chris@0 121 {
Chris@12 122 if (! is_array($value)) {
Chris@0 123 return false;
Chris@0 124 }
Chris@0 125
Chris@12 126 if (! $value) {
Chris@0 127 return $allowEmpty;
Chris@0 128 }
Chris@0 129
Chris@0 130 return (array_values($value) === $value);
Chris@0 131 }
Chris@0 132
Chris@0 133 /**
Chris@0 134 * Test whether an array is a hash table.
Chris@0 135 *
Chris@0 136 * An array is a hash table if:
Chris@0 137 *
Chris@0 138 * 1. Contains one or more non-integer keys, or
Chris@0 139 * 2. Integer keys are non-continuous or misaligned (not starting with 0)
Chris@0 140 *
Chris@0 141 * For example:
Chris@0 142 * <code>
Chris@0 143 * $hash = array(
Chris@0 144 * 'foo' => 15,
Chris@0 145 * 'bar' => false,
Chris@0 146 * );
Chris@0 147 * $hash = array(
Chris@0 148 * 1995 => 'Birth of PHP',
Chris@0 149 * 2009 => 'PHP 5.3.0',
Chris@0 150 * 2012 => 'PHP 5.4.0',
Chris@0 151 * );
Chris@0 152 * $hash = array(
Chris@0 153 * 'formElement,
Chris@0 154 * 'options' => array( 'debug' => true ),
Chris@0 155 * );
Chris@0 156 * </code>
Chris@0 157 *
Chris@0 158 * @param mixed $value
Chris@0 159 * @param bool $allowEmpty Is an empty array() a valid hash table?
Chris@0 160 * @return bool
Chris@0 161 */
Chris@0 162 public static function isHashTable($value, $allowEmpty = false)
Chris@0 163 {
Chris@12 164 if (! is_array($value)) {
Chris@0 165 return false;
Chris@0 166 }
Chris@0 167
Chris@12 168 if (! $value) {
Chris@0 169 return $allowEmpty;
Chris@0 170 }
Chris@0 171
Chris@0 172 return (array_values($value) !== $value);
Chris@0 173 }
Chris@0 174
Chris@0 175 /**
Chris@0 176 * Checks if a value exists in an array.
Chris@0 177 *
Chris@0 178 * Due to "foo" == 0 === TRUE with in_array when strict = false, an option
Chris@0 179 * has been added to prevent this. When $strict = 0/false, the most secure
Chris@0 180 * non-strict check is implemented. if $strict = -1, the default in_array
Chris@0 181 * non-strict behaviour is used.
Chris@0 182 *
Chris@0 183 * @param mixed $needle
Chris@0 184 * @param array $haystack
Chris@0 185 * @param int|bool $strict
Chris@0 186 * @return bool
Chris@0 187 */
Chris@0 188 public static function inArray($needle, array $haystack, $strict = false)
Chris@0 189 {
Chris@12 190 if (! $strict) {
Chris@0 191 if (is_int($needle) || is_float($needle)) {
Chris@0 192 $needle = (string) $needle;
Chris@0 193 }
Chris@0 194 if (is_string($needle)) {
Chris@0 195 foreach ($haystack as &$h) {
Chris@0 196 if (is_int($h) || is_float($h)) {
Chris@0 197 $h = (string) $h;
Chris@0 198 }
Chris@0 199 }
Chris@0 200 }
Chris@0 201 }
Chris@0 202 return in_array($needle, $haystack, $strict);
Chris@0 203 }
Chris@0 204
Chris@0 205 /**
Chris@0 206 * Convert an iterator to an array.
Chris@0 207 *
Chris@0 208 * Converts an iterator to an array. The $recursive flag, on by default,
Chris@0 209 * hints whether or not you want to do so recursively.
Chris@0 210 *
Chris@0 211 * @param array|Traversable $iterator The array or Traversable object to convert
Chris@0 212 * @param bool $recursive Recursively check all nested structures
Chris@0 213 * @throws Exception\InvalidArgumentException if $iterator is not an array or a Traversable object
Chris@0 214 * @return array
Chris@0 215 */
Chris@0 216 public static function iteratorToArray($iterator, $recursive = true)
Chris@0 217 {
Chris@12 218 if (! is_array($iterator) && ! $iterator instanceof Traversable) {
Chris@0 219 throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable object');
Chris@0 220 }
Chris@0 221
Chris@12 222 if (! $recursive) {
Chris@0 223 if (is_array($iterator)) {
Chris@0 224 return $iterator;
Chris@0 225 }
Chris@0 226
Chris@0 227 return iterator_to_array($iterator);
Chris@0 228 }
Chris@0 229
Chris@0 230 if (method_exists($iterator, 'toArray')) {
Chris@0 231 return $iterator->toArray();
Chris@0 232 }
Chris@0 233
Chris@0 234 $array = [];
Chris@0 235 foreach ($iterator as $key => $value) {
Chris@0 236 if (is_scalar($value)) {
Chris@0 237 $array[$key] = $value;
Chris@0 238 continue;
Chris@0 239 }
Chris@0 240
Chris@0 241 if ($value instanceof Traversable) {
Chris@0 242 $array[$key] = static::iteratorToArray($value, $recursive);
Chris@0 243 continue;
Chris@0 244 }
Chris@0 245
Chris@0 246 if (is_array($value)) {
Chris@0 247 $array[$key] = static::iteratorToArray($value, $recursive);
Chris@0 248 continue;
Chris@0 249 }
Chris@0 250
Chris@0 251 $array[$key] = $value;
Chris@0 252 }
Chris@0 253
Chris@0 254 return $array;
Chris@0 255 }
Chris@0 256
Chris@0 257 /**
Chris@0 258 * Merge two arrays together.
Chris@0 259 *
Chris@0 260 * If an integer key exists in both arrays and preserveNumericKeys is false, the value
Chris@0 261 * from the second array will be appended to the first array. If both values are arrays, they
Chris@0 262 * are merged together, else the value of the second array overwrites the one of the first array.
Chris@0 263 *
Chris@0 264 * @param array $a
Chris@0 265 * @param array $b
Chris@0 266 * @param bool $preserveNumericKeys
Chris@0 267 * @return array
Chris@0 268 */
Chris@0 269 public static function merge(array $a, array $b, $preserveNumericKeys = false)
Chris@0 270 {
Chris@0 271 foreach ($b as $key => $value) {
Chris@0 272 if ($value instanceof MergeReplaceKeyInterface) {
Chris@0 273 $a[$key] = $value->getData();
Chris@0 274 } elseif (isset($a[$key]) || array_key_exists($key, $a)) {
Chris@0 275 if ($value instanceof MergeRemoveKey) {
Chris@0 276 unset($a[$key]);
Chris@12 277 } elseif (! $preserveNumericKeys && is_int($key)) {
Chris@0 278 $a[] = $value;
Chris@0 279 } elseif (is_array($value) && is_array($a[$key])) {
Chris@0 280 $a[$key] = static::merge($a[$key], $value, $preserveNumericKeys);
Chris@0 281 } else {
Chris@0 282 $a[$key] = $value;
Chris@0 283 }
Chris@0 284 } else {
Chris@12 285 if (! $value instanceof MergeRemoveKey) {
Chris@0 286 $a[$key] = $value;
Chris@0 287 }
Chris@0 288 }
Chris@0 289 }
Chris@0 290
Chris@0 291 return $a;
Chris@0 292 }
Chris@0 293
Chris@0 294 /**
Chris@16 295 * @deprecated Since 3.2.0; use the native array_filter methods
Chris@0 296 *
Chris@0 297 * @param array $data
Chris@0 298 * @param callable $callback
Chris@0 299 * @param null|int $flag
Chris@0 300 * @return array
Chris@16 301 * @throws Exception\InvalidArgumentException
Chris@0 302 */
Chris@0 303 public static function filter(array $data, $callback, $flag = null)
Chris@0 304 {
Chris@0 305 if (! is_callable($callback)) {
Chris@0 306 throw new Exception\InvalidArgumentException(sprintf(
Chris@0 307 'Second parameter of %s must be callable',
Chris@0 308 __METHOD__
Chris@0 309 ));
Chris@0 310 }
Chris@0 311
Chris@16 312 return array_filter($data, $callback, $flag);
Chris@0 313 }
Chris@0 314 }