pulsarvp/vps-tools

View on GitHub
src/helpers/ArrayHelper.php

Summary

Maintainability
C
7 hrs
Test Coverage
<?php
    namespace vps\tools\helpers;

    /**
     * Class ArrayHelper
     *
     * @package vps\tools\helpers
     */
    class ArrayHelper extends \yii\helpers\BaseArrayHelper
    {
        /**
         * Adds column to multidimensional array. First level keys of $array must be the same as $column keys.
         * ```php
         * $array = [ 'a' => [ 1 ],
         *            'b' => [ 3 ],
         *            'c' => [ 2 ]
         * ];
         * $result = ArrayHelper::addColumn($array, [ 'a' => 4, 'b' => 6, 'c' => 7 ]);
         * // $result will be:
         * // [ 'a' => [ 1, 4 ],
         * // 'b' => [ 3, 6 ],
         * // 'c' => [ 2, 7 ]
         * // ]
         * ```
         *
         * @param  array $array
         * @param  array $column
         * @return array
         */
        public static function addColumn ($array, $column)
        {
            $return = $array;
            // Check if keys are the same.
            if (count($return) == count($column) and empty(array_diff(array_keys($return), array_keys($column))))
            {
                foreach ($return as $k => &$ret)
                    $ret[] = $column[ $k ];
            }

            return $return;
        }

        /**
         * Unsets an element and returns its value.
         * ```php
         * $array = [ 1,
         *          'a' => [
         *                  'b' => [
         *                      'b1' => 10,
         *                      'b2' => 20
         *                      ],
         *                  'c' => [ 10, 6 ]
         *                 ],
         *          'key' => 0, 10 ];
         * $result = ArrayHelper::delete($array, 'a');
         * // $result will be:
         * // [ 'b' =>
         * //         [
         * //             'b1' => 10,
         * //             'b2' => 20
         * //         ],
         * //     'c' => [ 10, 6 ]
         * //   ]
         *
         * // $array will be:
         * // [
         * //   0 => 1,
         * //   'key' => 0,
         * //   1 => 10
         * // ]
         * ```
         *
         * @param array  $array
         * @param string $key Key name of the array element, may be specified in a dot format to retrieve the value of a sub-array or the property of an embedded object.
         * @return mixed Value of the removed element.
         */
        public static function delete (&$array, $key)
        {
            $value = null;

            if (is_array($array) and ( is_string($key) or is_numeric($key) ))
            {

                if (array_key_exists($key, $array))
                {
                    $value = $array[ $key ];
                    unset($array[ $key ]);
                }

                if (( $pos = strpos($key, '.') ) !== false)
                {
                    $newkey = substr($key, 0, $pos);
                    if (array_key_exists($newkey, $array))
                        $value = static::delete($array[ $newkey ], substr($key, $pos + 1));
                }
            }

            return $value;
        }

        /**
         * Recursively sets all empty value in array to null.
         * ```php
         * $array = [ 1,
         *          'a' => [
         *                  'b' => [
         *                      'b1' => 0,
         *                      'b2' => 20
         *                      ],
         *                  'c' => [ 10, 6 ]
         *                 ],
         *          'key' => '', 10 ];
         * $result = ArrayHelper::emptyToNull($array);
         * // $result will be:
         * //  [
         * //       1,
         * //       'a' => [
         * //               'b' => [
         * //                     'b1' => null,
         * //                     'b2' => 20
         * //                     ],
         * //               'c' => [ 10, 6 ]
         * //              ],
         * //       'key' => null, 10 ]
         * ```
         *
         * @param  array $array
         * @return array|null Exactly the input array but with null values instead of empty ones. Null if $array is not array.
         */
        public static function emptyToNull ($array)
        {
            if (is_array($array))
            {
                $return = [];
                foreach ($array as $key => $item)
                {
                    if (empty($item))
                        $return[ $key ] = null;
                    elseif (is_array($item))
                        $return[ $key ] = self::emptyToNull($item);
                    else
                        $return[ $key ] = $item;
                }

                return $return;
            }

            return null;
        }

        /**
         * Checks if all elements in array are equal.
         * ```php
         * $result = ArrayHelper::equal([1,1,1,1])
         * // $result will be: true
         * ```
         *
         * @param array   $array
         * @param boolean $strict Whether strict comparison should be used.
         * @return boolean|null
         */
        public static function equal ($array, $strict = false)
        {
            if (is_array($array))
            {
                if ($strict)
                {
                    $data = array_values($array);
                    for ($i = 0; $i < count($data); $i++)
                    {
                        for ($j = $i + 1; $j < count($data); $j++)
                            if ($data[ $i ] !== $data[ $j ])
                                return false;
                    }

                    return true;
                }
                else
                    return ( count(array_unique($array)) === 1 );
            }
            else
                return null;
        }

        /**
         * Selects from the array given keys.
         * ```php
         * $result = ArrayHelper::filterKeys([ 1, 3, 3, 8 ], [ 1, 3 ]);
         * // $result will be:
         * // [ 1 => 3, 3 => 8 ]
         * ```
         *
         * @param  array $array
         * @param  array $keys
         * @return array Values found with their corresponding keys.
         */
        public static function filterKeys ($array, $keys)
        {
            if (is_array($array))
            {
                $return = [];
                if (!is_array($keys))
                    $keys = [ $keys ];
                foreach ($keys as $key)
                    if (isset($array[ $key ]))
                        $return[ $key ] = $array[ $key ];

                return $return;
            }

            return null;
        }

        /**
         * Flattens multidimensional array. Does not preserve key.
         * ```php
         * $array = [
         *          1,
         *          'a' => [
         *                  'b' => [
         *                          'b1' => 10,
         *                          'b2' => 20
         *                          ],
         *                  'c' => [ 10, 6 ]
         *                  ],
         *          'key' => 0, 10]
         *          ]
         * $result = ArrayHelper::flatten($array);
         * // $result will be:
         * // [ 1, 10, 20, 10, 6, 0, 10 ]
         * ```
         *
         * @param  array $array Array to be flattened.
         * @return array Flattened array.
         */
        public static function flatten ($array)
        {
            if (!is_array($array))
                return null;

            $flatten = [];
            $it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array));
            foreach ($it as $v)
                $flatten[] = $v;

            return $flatten;
        }

        /**
         * Checks if all keys exist in given array.
         * ```php
         * $result = ArrayHelper::keysExist([ 1, 2, 3 ], 1);
         * // $result will be: true
         * ```
         *
         * @param array $array
         * @param array $keys
         * @return bool|null
         */
        public static function keysExist ($array, $keys)
        {
            if (!is_array($array))
                return null;

            if (!is_array($keys))
                $keys = [ $keys ];

            foreach ($keys as $key)
                if (!array_key_exists($key, $array))
                    return false;

            return true;
        }

        /**
         * Merges columns of the same length in multi-array.
         * ```php
         * $result = ArrayHelper::mergeColumns([ 1, 2, 3 ], [ 4, 5, 6 ]);
         * // $result will be:
         * // [
         * //   [ 1, 4 ],
         * //   [ 2, 5 ],
         * //   [ 3, 6 ]
         * // ]
         * ```
         *
         * @param  array $column1
         * @param  array $column2
         * @param  array $column3 ...
         * @return array | null
         */
        public static function mergeColumns ()
        {
            $count = [];
            $args = func_get_args();

            if (count($args) == 0)
                return [];

            foreach ($args as $arg)
            {
                if (!is_array($arg))
                    return null;
                $count[] = count($arg);
            }

            if (!self::equal($count))
                return null;

            $data = [];
            $n = $count[ 0 ];
            for ($i = 0; $i < $n; $i++)
            {
                $item = [];
                foreach ($args as $arg)
                    $item[] = $arg[ $i ];
                $data[] = $item;
            }

            return $data;
        }

        /**
         * Gets random elements from array.
         * ```php
         * $result = ArrayHelper::mix([1,2,3,4,5],2);
         * // $result will be:
         * // [2,5]
         * ```
         *
         * @param array   $array Input array.
         * @param integer $num Number of element to extract.
         * @return array|null Array with random element from $array. Null if $array is not array.
         */
        public static function mix ($array, $num)
        {
            if (is_array($array))
            {
                $data = [];
                $num = min($num, count($array));
                if ($num > 0)
                {
                    $keys = array_rand($array, $num);
                    if (!is_array($keys))
                        $keys = [ $keys ];
                    foreach ($keys as $key)
                        $data[] = $array[ $key ];
                }

                return $data;
            }

            return null;
        }

        /**
         * Get given attribute from array of objects.
         * ```php
         * [
         * 'app\models\Post' => [
         *         'id'=> '2',
         *         'name' => 'Name',
         *         'createTime' => 'created_at',
         *     ],
         * 'app\models\Post' => [
         *         'id'=> '3',
         *         'name' => 'NameTwo',
         *         'createTime' => 'created_at',
         *     ],
         * ]
         *
         * $result = ArrayHelper::objectsAttribute($object, 'name');
         * // $result will be:
         * // ['Name','NameTwo']
         * ```
         *
         * @param  array  $objects
         * @param  string $attribute Attribute name.
         * @return array
         */
        public static function objectsAttribute ($objects, $attribute)
        {
            if (!is_array($objects))
                return null;

            $data = [];
            foreach ($objects as $object)
                $data[] = isset ($object->$attribute) ? $object->$attribute : null;

            return $data;
        }

        /**
         * Recursively finds given attribute from array of objects.
         * ```php
         * [
         * 'app\models\Post' => [
         *         'id'=> '2',
         *         'name' => 'Name',
         *         'createTime' => 'created_at',
         *         'children' => [
         *                  'app\models\Post' => [
         *                          'id'=> '3',
         *                           'name' => 'NameTwo',
         *                           'createTime' => 'created_at',
         *                           ],'
         *                     ],
         *      'app\models\Post' => [
         *         'id'=> '3',
         *         'name' => 'NameThree',
         *         'createTime' => 'created_at',
         *     ],
         * ]
         *
         * $result = ArrayHelper::objectsAttributeRecursive($object, 'name');
         * // $result will be:
         * // ['Name','NameTwo','NameThree']
         * ```
         *
         * @param  array  $objects
         * @param  string $attribute Attribute name.
         * @param  string $children Children attribute name.
         * @return array
         */
        public static function objectsAttributeRecursive ($objects, $attribute, $children = 'children')
        {
            if (!is_array($objects))
                return null;

            $data = [];
            foreach ($objects as $item)
            {
                if (isset($item->$attribute))
                    $data[] = $item->$attribute;
                if (isset($item->$children))
                    $data = array_merge($data, self::objectsAttributeRecursive($item->$children, $attribute, $children));
            }

            return $data;
        }

        /**
         * Set array to multidimensional array.
         * ```php
         * $array = [ 1,
         *          'a' => [
         *                  'b' => [
         *                      'b1' => 10,
         *                      'b2' => 20
         *                      ],
         *                  'c' => [ 10, 6 ]
         *                 ],
         *          'key' => 0, 10 ];
         *
         * $result = ArrayHelper::setValue($array, 'a.d', 15);
         * // $result will be:
         * // [ 1,
         * //   'a' => [
         * //           'b' => [
         * //                  'b1' => 10,
         * //                   'b2' => 20
         * //                  ],
         * //           'c' => [ 10, 6 ],
         * //           'd' => 15
         * //          ],
         * //  'key' => 0, 10
         * // ]
         * ```
         *
         * @param array  $array
         * @param string $key Key name of the array element, may be specified in a dot format to retrieve the value fof a sub-array or the property of an embedded object.
         * @param mixed  $value Value to be set.
         */
        public static function setValue (&$array, $key, $value)
        {
            if (is_array($array) and ( is_string($key) or is_numeric($key) ))
            {
                if (( $pos = strpos($key, '.') ) === false)
                {
                    $array[ $key ] = $value;
                }
                else
                {
                    $newkey = substr($key, 0, $pos);
                    if (!is_array($array) or !array_key_exists($newkey, $array))
                        $array[ $newkey ] = [];
                    static::setValue($array[ $newkey ], substr($key, $pos + 1), $value);
                }
            }
        }

        /**
         * Checks whether given array is associative.
         * ```php
         * $result = ArrayHelper::isAssoc(['a'=>'b']);
         * // $result will be: true
         * ```
         *
         * @param  array $a
         * @return boolean
         */
        public static function isAssoc ($a)
        {
            foreach (array_keys($a) as $key)
                if (!is_int($key))
                    return true;

            return false;
        }
    }