PHP: могу ли я получить индекс в функции карты массива?
Я использую карту в PHP вот так:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
можно ли получить индекс значения в функцию?
также-если я пишу код, который нуждается в индексе, должен ли я использовать цикл for вместо карты?
3 ответов:
конечно, вы можете, с помощью
array_keys():function func($v, $k) { // key is now $k return $v * 2; } $values = array(4, 6, 3); $mapped = array_map(func, $values, array_keys($values)); var_dump($mapped);
при отображении анонимной функции на анонимный массив, нет никакого способа получить доступ к ключам:
array_map( function($val) use ($foo) { /* ... */ }, array(key1 => val1, key2 => val2, /* ... */));array_reduce также не получает доступа к ключам. array_walk может получить доступ к ключам, но массив передается по ссылке, что требует уровня косвенности.
некоторые решения являются:
массив пар
это плохо, так как мы меняем исходный массив. Плюс шаблонный" array () " вызовы увеличиваются линейно с помощью длина массива:
array_map( function($pair) use ($foo) { list($key, $val) = $pair; /* ... */ }, array(array(key1, val1), array(key2, val2), /* ... */));временная переменная
мы действуем на исходный массив, и шаблон является постоянным, но мы можем легко сбить существующую переменную:
$i_hope_this_does_not_conflict = array(key1 => val1, key2 => val2, /* ... */); array_map( function($key, $val) use ($foo) { /* ... */ }, array_keys($i_hope_this_does_not_conflict), $i_hope_this_does_not_conflict); unset($i_hope_this_does_not_conflict);функция одного выстрела
мы можем использовать область действия функции для предотвращения clobbering существующих имен, но должны добавить дополнительный слой "use":
call_user_func( function($arr) use ($foo) { return array_map(function($key, $val) use ($foo) { /* ... */ }, array_keys($arr), $arr); }, array(key1 => val1, key2 => val2, /* ... */));многопараметрическая одноразовая функция
мы определяем функцию, которую мы сопоставляем в оригинальная область для предотвращения" использования " шаблона):
call_user_func( function($f, $arr) { return array_map($f, array_keys($arr), $arr); }, function($key, $val) use ($foo) { /* ... */ }, array(key1 => val1, key2 => val2, /* ... */));новая функция
интересно отметить, что наша последняя одноразовая функция имеет хорошую общую подпись и очень похожа на array_map. Мы могли бы дать этому имя и повторно использовать его:
наш код приобретает следующий вид:function array_mapk($f, $arr) { return array_map($f, array_keys($arr), $arr); }array_mapk( function($key, $val) use ($foo) { /* ... */ }, array(key1 => val1, key2 => val2, /* ... */));Косвенная Прогулка Массива
при написании выше я проигнорировал array_walk, так как он требует, чтобы его аргумент был прошел по ссылке, однако, я так понял, что это легко обойти с помощью call_user_func. Я думаю, что это лучшая версия до сих пор:
call_user_func( 'array_walk', array(key1 => val1, key2 => val2, /* ... */), function($val, $key) use ($foo) { /* ... */ });
отсутствует параметр в выпадающем классе. Я думаю, что это лучше так:
public function options() { $value = $this->value; $mapped = array_map(function($k, $v) use ($value) { return array( 'value' => $k, 'display' => $v, 'selected' => ($value === $k), ); }, array_keys($this->options), $this->options); return $mapped; }
Comments