Предложение добавить ArrayHelper::append

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка, а также внесение новых предложений.
Ответить
Lander
Сообщения: 3
Зарегистрирован: 2016.08.24, 15:54

Предложение добавить ArrayHelper::append

Сообщение Lander »

Очень часто приходится возиться с if ( !isset($array['idx']) ) { $array['idx'] = ...; }
Вышел из положения следующим расширением ArrayHelper

Код: Выделить всё

class ArrayHelper extends \yii\helpers\ArrayHelper
{
    /**
     * Добавляет в массив значение $value в соответствии с иерархией ключей
     * $indexes
     * @param array $array
     * @param array|string $indexes
     * @param mixed $value
     * @return array
     */
    public static function append($array, $indexes, $value = [])
    {
        if ( !is_array($array)) {
            return $array; }
            
        if ( !is_array($indexes) ) {
            $indexes = explode('.', $indexes); }
            
        $idx = array_values($indexes)[0];
        
        if ( count($indexes) > 1) {
            $array[$idx] = isset($array[$idx]) ? $array[$idx] : []; 
            $array[$idx] = self::append($array[$idx], array_slice($indexes, 1), $value);
        } elseif ( !isset($array[$idx]) ) { 
            $array[$idx] = $value; 
        }        
        
        return $array;
    }            
}
Метод на основании списка ключей $indexes выстраивает структуру элементов массива и если конечный элемент не задан, то устанавливает его в $value.

Код: Выделить всё

$arr = [
    0 => [
        'idx' => 2,
        'pdx' => 3
    ],
    1 => [
        'idx' => 10
    ]
];
$arr1 = ArrayHelper::append($arr, [1, 'pdx'], 11); 
$arr2 = ArrayHelper::append($arr, '1.pdx', 11);
/*
Массивы $arr1 и $arr2 - идентичны.

[
    0 => [
        'idx' => 2,
        'pdx' => 3
    ],
    1 => [
        'idx' => 10,
        'pdx' => 11
    ]
];

*/
Предлагаю перенести этот метод в \yii\helpers\ArrayHelper.
Последний раз редактировалось Lander 2016.08.24, 18:01, всего редактировалось 1 раз.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Предложение добавить ArrayHelper::append

Сообщение zelenin »

Код: Выделить всё

$array['idx'] = isset($array['idx']) ? $array['idx']  : 10;
$array['idx'] = ArrayHelper::getValue($array, 'idx', 10); 
Lander
Сообщения: 3
Зарегистрирован: 2016.08.24, 15:54

Re: Предложение добавить ArrayHelper::append

Сообщение Lander »

Осталось понять как это соотносится с тем что я предлагаю...
Про getValue знаю. На получение значения. А мой метод для создания структуры.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Предложение добавить ArrayHelper::append

Сообщение zelenin »

Lander писал(а):Осталось понять как это соотносится с тем что я предлагаю...
Про getValue знаю. На получение значения. А мой метод для создания структуры.
Ваш пример:

Код: Выделить всё

$arr = [
    0 => [
        'idx' => 2,
        'pdx' => 3
    ],
    1 => [
        'idx' => 10
    ]
];
$arr2 = ArrayHelper::append($arr, '1.pdx', 11);
работает также как и:

Код: Выделить всё

$arr = [
    0 => [
        'idx' => 2,
        'pdx' => 3
    ],
    1 => [
        'idx' => 10
    ]
];
arr2 = $arr;
$arr2[1]['pdx'] = ArrayHelper::getValue($arr, '1.pdx', 11);
поэтому мне кажется ваше предложение излишне, т.к. решает проблему а) присвоения элементу массива значения б) задания дефолтного значения, если конечного значения не существует.
все это уже решено.
Если же я не понял смысла вашего кода, то поясните - много букаф.
Lander писал(а):А мой метод для создания структуры.
Структура автоматически создается при присвоении значения элементу массива.
Lander
Сообщения: 3
Зарегистрирован: 2016.08.24, 15:54

Re: Предложение добавить ArrayHelper::append

Сообщение Lander »

Код: Выделить всё

$arr = [
    0 => [
        'idx' => 2,
        'pdx' => 3
    ],
    1 => [
        'idx' => 10
    ]
];
$arr = ArrayHelper::append($arr, '3.user.name', 'Иванов Иван Иванович');
/*
$arr = [
    0 => [
        'idx' => 2,
        'pdx' => 3
    ],
    1 => [
        'idx' => 10
    ],
    3 => [
        'user' => [
            'name' => 'Иванов Иван Иванович'
        ],
    ],
];
*/
Обычным способом мне бы понадобилось проверить isset($arr[3]), потом isset($arr[3]['user'])и только потом $arr[3]['user']['name'] = 'Иванов Иван Иванович'. Думаю понятно что глубина может быть гораздо больше. Особенно это заметно когда из API данные пытаешься какие то отдать в JSON-формате. Например у меня таких уровней сегодня было 6!
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Предложение добавить ArrayHelper::append

Сообщение zelenin »

значит все-таки правильно понял:

Код: Выделить всё

$arr[3]['user']['name'] = ArrayHelper::getValue($arr, '3.user.name', 'Иванов Иван Иванович'); 
Ответить