Изменение ключей массива в функции array_walk?
Я использую функции массива, чтобы преобразовать строку, связанную с строкой, в ассоциативный массив.
$piper = "|k=f|p=t|e=r|t=m|";
$piper = explode("|",$piper);
$piper = array_filter($piper);
function splitter(&$value,$key) {
$splitted = explode("=",$value);
$key = $splitted[0];
$value = $splitted[1];
}
array_walk($piper, 'splitter');
var_dump($piper);
это дает мне
array (size=4)
1 => string 'f' (length=1)
2 => string 't' (length=1)
3 => string 'r' (length=1)
4 => string 'm' (length=1)
где я хочу:
array (size=4)
"k" => string 'f' (length=1)
"p" => string 't' (length=1)
"e" => string 'r' (length=1)
"t" => string 'm' (length=1)
но ключи не изменяются. Есть ли какая-либо функция массива, с которой я могу перебирать массив и менять ключи и значения?
Ответы
Ответ 1
В документации array_walk (описание функции обратного вызова):
Можно изменять только значения массива; его структура не могут быть изменены, то есть программист не может добавлять, отменять или изменять порядок элементы. Если обратный вызов не соблюдает это требование, поведение этой функции undefined и непредсказуемо.
Это означает, что вы не можете использовать array_walk
для изменения ключей итерированного массива. Однако вы можете создать с ним новый массив:
$result = array();
array_walk($piper, function (&$value,$key) use (&$result) {
$splitted = explode("=",$value);
$result[ $splitted[0] ] = $splitted[1];
});
var_dump($result);
Тем не менее, я думаю, что если бы это был я, я использовал бы здесь регулярное выражение (вместо "взрывающегося взорванного" ):
$piper = "|k=f|p=t|e=r|t=m|";
preg_match_all('#([^=|]*)=([^|]*)#', $piper, $matches, PREG_PATTERN_ORDER);
$piper = array_combine($matches[1], $matches[2]);
var_dump($piper);
Ответ 2
Для этого лучше использовать foreach
. В следующем примере показана обработка записи, добавление ее правой клавишей и удаление исходной записи.
$piper = "|k=f|p=t|e=r|t=m|";
$piper = array_filter(explode("|", $piper));
foreach ($piper as $index => $value) {
list($key, $value) = explode("=", $value);
$piper[$key] = $value;
unset($piper[$index]);
}
Позаботьтесь, чтобы у вас не было ключей, похожих на индекс.
Другой альтернативой является обработка значений посредством ссылки и установка ключей после этого:
foreach ($piper as &$value) {
list($keys[], $value) = explode("=", $value);
}
unset($value);
$piper = array_combine($keys, $piper);
Это не приводит к возникновению каких-либо проблем, но только с дублирующими ключами. Но вы можете проверить эту проблему после foreach
, никакие данные не будут потеряны.
Что-то, что не может быть гарантировано со следующим foreach
, которое, вероятно, наиболее упрощено путем обращения к массиву результатов:
$result = array();
foreach ($piper as $value) {
list($key, $value) = explode("=", $value);
$result[$key] = $value;
}
Ответ 3
Почему бы не построить новый массив, который имеет нужные ключи и значения из $piper?
$piper2 = array();
foreach ($piper as $k => $val)
{
$splitted = explode("=", $val);
$key = $splitted[0];
$value = $splitted[1];
$piper2[$key] = $value;
}
$piper = $piper2; // if needed
Ответ 4
Использование array_reduce сделает трюк
$piper = "|k=f|p=t|e=r|t=m|";
$piper = explode("|",$piper);
$piper = array_filter($piper);
function splitter($result, $item) {
$splitted = explode("=",$item);
$key = $splitted[0];
$value = $splitted[1];
$result[$key] = $value;
return $result;
}
$piper = array_reduce($piper, 'splitter', array());
var_dump($piper);
на основе этого: http://www.danielauener.com/howto-use-array_map-on-associative-arrays-to-change-values-and-keys/
Ответ 5
Это моя рекурсивная функция, которая может изменять не только значения массива как array_walk_recursive() , но также ключи данного массива. Он также сохраняет порядок массива:fooobar.com/info/897708/...