Чем ссылка в первом варианте лучше ссылки во втором и существует ли подобный первому способ передачи ссылки в функцию обратного вызова, но "более общепринятый, стандарнтый, понятный и т.п."? PHP: <?php $extLang = [ 'rb' => 'Ruby', '*.py' => 'Python', '*.php' => 'PHP', 'js' => 'JavaScript', ]; array_walk($extLang, 'counter', [&$extLang]); function counter($item, $key, $arr): void { if (is_string($item)) { if (isset($arr[0][0]['maxItemLen'])) { $len = strlen($item); if ($len > $arr[0][0]['maxItemLen']) { $arr[0][0]['maxItemLen'] = $len; } } else { $arr[0][0]['maxItemLen'] = strlen($item); } } } array_walk($extLang, 'counter2', $linkExtLang = &$extLang); function counter2($item, $key, $arr): void { if (is_string($item)) { if (isset($arr[0]['maxItemLen'])) { $len = strlen($item); if ($len > $arr[0]['maxItemLen']) { $arr[0]['maxItemLen'] = $len; } } else { $arr[0]['maxItemLen'] = strlen($item); } } } var_export($extLang);
Добрый день! Вариант 1 лучше чем 2 потому, что 2 вариант не работает. Вашу функцию counter немного переделал. PHP: <?php echo "<pre>"; $extLang = [ 'rb' => 'Ruby', '*.py' => 'Python', '*.php' => 'PHP', 'js' => 'JavaScript', ]; array_walk($extLang, 'counter', [&$extLang]); /* function counter($item, $key, $arr): void { if (is_string($item)) { if (isset($arr[0][0]['maxItemLen'])) { $len = strlen($item); if ($len > $arr[0][0]['maxItemLen']) { $arr[0][0]['maxItemLen'] = $len; } } else { $arr[0][0]['maxItemLen'] = strlen($item); } } } */ function counter($item, $key, $arr): void { arr[0][0]['maxItemLen'] = max( $arr[0][0]['maxItemLen'], strlen($item) ); } echo "1. Вариант<br>\$extLang "; print_r($extLang); $extLang = [ 'rb' => 'Ruby', '*.py' => 'Python', '*.php' => 'PHP', 'js' => 'JavaScript', ]; array_walk($extLang, 'counter2', $linkExtLang = &$extLang); function counter2($item, $key, $arr): void { if (is_string($item)) { if (isset($arr[0]['maxItemLen'])) { $len = strlen($item); if ($len > $arr[0]['maxItemLen']) { $arr[0]['maxItemLen'] = $len; } } else { $arr[0]['maxItemLen'] = strlen($item); } } } echo "2. Вариант<br>\$extLang "; print_r($extLang); /* 1. Вариант $extLang Array ( [rb] => Ruby [*.py] => Python [*.php] => PHP [js] => JavaScript [0] => Array ( [maxItemLen] => 10 ) ) 2. Вариант $extLang Array ( [rb] => Ruby [*.py] => Python [*.php] => PHP [js] => JavaScript ) */ Удачи!
У Вас отменное чувство юмора, однако . Я вот полтора часа потратил, чтобы понять почему не работает, но так и не понял... Чтож, опыт не пропьешь! И Вам удачи! Спасибо за ответ!
Всеравно, к одной строчке не получится свести - т.к. в начале maxItemLen не существует, а в конце в strlen попадет массив: PHP: function counter($item, $key, $arr): void { if (is_string($item)) { if (!isset($arr[0][0]['maxItemLen'])) { $arr[0][0]['maxItemLen'] = 0; } $arr[0][0]['maxItemLen'] = max($arr[0][0]['maxItemLen'], strlen($item)); } }
Однако и одна строчка работает. Поставьте ради интереса error_reporting(E_ALL). Предупреждения не выдаются. Если и добавлять в функции проверку то достаточно только одну PHP: $arr[0][0]['maxItemLen'] = 0; array_walk($extLang, 'counter', [&$extLang]); function counter($item, $key, $arr): void { if (is_string($item)) $arr[0][0]['maxItemLen'] = max($arr[0][0]['maxItemLen'], strlen($item)); }
(дополнение) Если Вам требуется вычислить maxItemLen и при этом не обязательно применять функцию array_walk, то можно сделать так: PHP: $extLang = [ 'rb' => 'Ruby', '*.py' => 'Python', '*.php' => 'PHP', 'js' => 'JavaScript', ]; $maxItemLen = max(array_map('counter', $extLang)); function counter($item) { return strlen($item); } echo "maxItemLen = ", $maxItemLen; /* maxItemLen = 10 */ P.S. При этом массив исходых данных не будет переписан.
Этот вариант мне и вправду нравится! Но, тогда логичнее написать просто: PHP: $maxItemLen = max(array_map('strlen', $extLang)); Но по сути, я не ищу способа как обойти массив, а просто разбираюсь с языком. Вот дочитал я книжку до функции array_walk(). И вижу, что ей можно передать третий параметр. Стал размышлять на тему, каким этот параметр может быть, чтобы это было и вправду полезно. Возникла идея, что если бы был конвеер из array_walk(), то можно было бы подать на вход некоторый массив, и на нем что-то вычислить и получить результат. А при необходимости такой конвеер можно было бы легко перестраивать. Вот в этот момент и возникла мутная ситуация. Почему я в array_walk() могу сделать передачу внешнего массива по ссылке, только в том случае, если в качестве носителя этой ссылки будет массив? А если в качестве носителя ссылки будет переменная, то ничего не получается? Это какое-то особое поведение array_walk, или так в остальных подобных функциях? Чем ссылка сохраненная в переменной отличается от ссылки сохраненной в массиве? В общем, я надеюсь найти ответы на эти вопросы здесь на форуме. Заранее всем спасибо!