Я использую карту в php так:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
Можно ли получить индекс значения в функции?
Кроме того, если я пишу код, которому нужен индекс, следует ли использовать цикл for вместо карты?
array_map()
произвольное количество аргументов :)array_keys
, останутся в том же порядке, что и в исходном массиве. Таким образом, вы можете сопоставить ключи с неправильными значениями. Безопасный подход - использовать толькоarray_keys
в качестве второго аргумента,array_map
а затем передать массив для закрытия с помощьюuse
оператора.При отображении анонимной функции на анонимный массив нет возможности получить доступ к ключам:
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);
Одноразовая функция
Мы можем использовать область видимости функции, чтобы предотвратить затирание существующих имен, но должны добавить дополнительный уровень «использования»:
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) { /* ... */ });
источник
Очень просто:
Только функция array_map: не имеет индексного ключа!
$params = [4,6,2,11,20]; $data = array_map(function($v) { return ":id{$v}";}, $params); array (size=5) 0 => string ':id4' (length=4) 1 => string ':id6' (length=4) 2 => string ':id2' (length=4) 3 => string ':id11' (length=5) 4 => string ':id20' (length=5)
Теперь объедините с array_keys:
$data = array_map( function($k) use ($params) { return ":id{$k}_${params[$k]}"; }, array_keys($params) ); array (size=5) 0 => string ':id0_4' (length=6) 1 => string ':id1_6' (length=6) 2 => string ':id2_2' (length=6) 3 => string ':id3_11' (length=7) 4 => string ':id4_20' (length=7)
источник
Вы можете создать свою собственную функцию карты, используя
foreach
:<?php function myCallback($key, $val) { var_dump("myCallback - key: $key, val: $val"); return $val * 2; } function foreachMap($callback, $givenArray) { $result = []; foreach ($givenArray as $key=>$val) { $result[$key] = $callback($key, $val); } return $result; } $values = array(4, 6, 3); $mapped = foreachMap('myCallback', $values); var_dump($mapped);
попробуйте: https://3v4l.org/pmFlB
источник