'123', 'data' => 'abc', 'device' => 'laptop'], * ['id' => '345', 'data' => 'def', 'device' => 'tablet'], * ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'], * ]; * $result = ArrayHelper::index($array, 'id'); * ``` * * The result will be an associative array, where the key is the value of `id` attribute * * ```php * [ * '123' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop'], * '345' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'] * // The second element of an original array is overwritten by the last element because of the same id * ] * ``` * * An anonymous function can be used in the grouping array as well. * * ```php * $result = ArrayHelper::index($array, function ($element) { * return $element['id']; * }); * ``` * * Passing `id` as a third argument will group `$array` by `id`: * * ```php * $result = ArrayHelper::index($array, null, 'id'); * ``` * * The result will be a multidimensional array grouped by `id` on the first level, by `device` on the second level * and indexed by `data` on the third level: * * ```php * [ * '123' => [ * ['id' => '123', 'data' => 'abc', 'device' => 'laptop'] * ], * '345' => [ // all elements with this index are present in the result array * ['id' => '345', 'data' => 'def', 'device' => 'tablet'], * ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'], * ] * ] * ``` * * The anonymous function can be used in the array of grouping keys as well: * * ```php * $result = ArrayHelper::index($array, 'data', [function ($element) { * return $element['id']; * }, 'device']); * ``` * * The result will be a multidimensional array grouped by `id` on the first level, by the `device` on the second one * and indexed by the `data` on the third level: * * ```php * [ * '123' => [ * 'laptop' => [ * 'abc' => ['id' => '123', 'data' => 'abc', 'device' => 'laptop'] * ] * ], * '345' => [ * 'tablet' => [ * 'def' => ['id' => '345', 'data' => 'def', 'device' => 'tablet'] * ], * 'smartphone' => [ * 'hgi' => ['id' => '345', 'data' => 'hgi', 'device' => 'smartphone'] * ] * ] * ] * ``` * * @param array $array the array that needs to be indexed or grouped * @param string|\Closure|null $key the column name or anonymous function which result will be used to index the array * @param string|string[]|\Closure[]|null $groups the array of keys, that will be used to group the input array * by one or more keys. If the $key attribute or its value for the particular element is null and $groups is not * defined, the array element will be discarded. Otherwise, if $groups is specified, array element will be added * to the result array without any key. This parameter is available since version 2.0.8. * @return array the indexed and/or grouped array */ public static function index($array, $key, $groups = []) { $result = []; $groups = (array) $groups; foreach ($array as $element) { $lastArray = &$result; foreach ($groups as $group) { $value = static::getValue($element, $group); if (!array_key_exists($value, $lastArray)) { $lastArray[$value] = []; } $lastArray = &$lastArray[$value]; } if ($key === null) { if (!empty($groups)) { $lastArray[] = $element; } } else { $value = static::getValue($element, $key); if ($value !== null) { if (is_float($value)) { $value = StringHelper::floatToString($value); } $lastArray[$value] = $element; } } unset($lastArray); } return $result; } /** * Retrieves the value of an array element or object property with the given key or property name. * If the key does not exist in the array, the default value will be returned instead. * Not used when getting value from an object. * * The key may be specified in a dot format to retrieve the value of a sub-array or the property * of an embedded object. In particular, if the key is `x.y.z`, then the returned value would * be `$array['x']['y']['z']` or `$array->x->y->z` (if `$array` is an object). If `$array['x']` * or `$array->x` is neither an array nor an object, the default value will be returned. * Note that if the array already has an element `x.y.z`, then its value will be returned * instead of going through the sub-arrays. So it is better to be done specifying an array of key names * like `['x', 'y', 'z']`. * * Below are some usage examples, * * ```php * // working with array * $username = \yii\helpers\ArrayHelper::getValue($_POST, 'username'); * // working with object * $username = \yii\helpers\ArrayHelper::getValue($user, 'username'); * // working with anonymous function * $fullName = \yii\helpers\ArrayHelper::getValue($user, function ($user, $defaultValue) { * return $user->firstName . ' ' . $user->lastName; * }); * // using dot format to retrieve the property of embedded object * $street = \yii\helpers\ArrayHelper::getValue($users, 'address.street'); * // using an array of keys to retrieve the value * $value = \yii\helpers\ArrayHelper::getValue($versions, ['1.0', 'date']); * ``` * * @param array|object $array array or object to extract value from * @param string|\Closure|array $key key name of the array element, an array of keys or property name of the object, * or an anonymous function returning the value. The anonymous function signature should be: * `function($array, $defaultValue)`. * The possibility to pass an array of keys is available since version 2.0.4. * @param mixed $default the default value to be returned if the specified array key does not exist. Not used when * getting value from an object. * @return mixed the value of the element if found, default value otherwise */ public static function getValue($array, $key, $default = null) { if ($key instanceof \Closure) { return $key($array, $default); } if (is_array($key)) { $lastKey = array_pop($key); foreach ($key as $keyPart) { $array = static::getValue($array, $keyPart); } $key = $lastKey; } if (is_array($array) && (isset($array[$key]) || array_key_exists($key, $array))) { return $array[$key]; } if (($pos = strrpos($key, '.')) !== false) { $array = static::getValue($array, substr($key, 0, $pos), $default); $key = substr($key, $pos + 1); } if (is_object($array)) { // this is expected to fail if the property does not exist, or __get() is not implemented // it is not reliably possible to check whether a property is accessible beforehand return $array->$key; } elseif (is_array($array)) { return (isset($array[$key]) || array_key_exists($key, $array)) ? $array[$key] : $default; } return $default; } /** * 在数组中按字段查找元素 * @param array $arr 待查找的数组 * @param string $colName 字段 * @param $colValue 匹配的值,完全匹配 * @param bool $findOne 是否只返回第一个匹配到的值 * @return array|mixed */ public static function array_column_search(array $arr, $colName, $colValue, $findOne = true) { if (count($arr) == 0) { return []; } $result = []; if ($findOne) { foreach ($arr as $item) { if ($item[$colName] == $colValue) { return $item; } } } else { foreach ($arr as $item) { if ($item[$colName] == $colValue) { $result[] = $item; } } } return $result; } /** * 截取二维数组的指定字段 * @param $array * @param $colmns * @return array */ public static function extractColumn($array, $colmns) { $return = []; foreach ($array as $item) { $tmp = []; foreach($colmns as $key=>$colmn){ if (array_key_exists($colmn, $item)) { $tmp[$colmn] = $item[$colmn]; }else{ $tmp[$colmn] = ''; } } $return[] = $tmp; } return $return; } /** * 两个数组的值做减法,挑选出存在于A,但不存在于B的元素 * @param $vectorA * @param $vectorB * @return array */ public static function restaDeArrays($vectorA, $vectorB) { $cantA = count($vectorA); $cantB = count($vectorB); $No_saca = 0; for ($i = 0; $i < $cantA; $i++) { for ($j = 0; $j < $cantB; $j++) { if ($vectorA[$i] == $vectorB[$j]) { $No_saca = 1; } } if ($No_saca == 0) { $nuevo_array[] = $vectorA[$i]; } else { $No_saca = 0; } } return $nuevo_array; } /** * 数组元素叠加 * @param $ini * @param $append * @return mixed */ public static function array_plus($ini, $append) { foreach ($append as $key => $value) { if (array_key_exists($key, $ini)) { $ini[$key] += $value; } else { $ini[$key] = $value; } } return $ini; } public static function array_random(array $array) { $array = array_values($array); return $array[mt_rand(0, count($array) - 1)]; } /** * 查询数组中是否含有指定key,不存在返回空 * @param $array * @param $key * @return mixed|string */ public static function array_find($array, $key) { if (!$array) { return ''; } if (array_key_exists($key, $array)) { return $array[$key]; } $fields = explode('.', $key); if (count($fields) > 1) { if (array_key_exists($fields[0], $array)) { $first = array_shift($fields); return self::array_find($array[$first], implode('.', $fields)); } } return ''; } public static function array_replace_key($array, $replace) { foreach ($array as $field => $value) { if (array_key_exists($field, $replace)) { unset($array[$field]); $array[$replace[$field]] = $value; } } return $array; } }