在array_walk函数中更改数组键?

时间:2012-11-07 13:42:18

标签: php arrays function

我正在使用数组函数将我的管道分隔字符串转换为关联数组。

$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)

但键没有改变。是否有任何数组函数可用于循环数组并更改键和值?

5 个答案:

答案 0 :(得分:53)

array_walk的文档中说(描述回调函数):

  

只有数组的值可能会被更改;它的结构   不能改变,即程序员不能添加,取消设置或重新排序   元素。如果回调不符合此要求,则   此函数的行为未定义且不可预测。

这意味着你不能使用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);

答案 1 :(得分:3)

您可以更好地使用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;
}

答案 2 :(得分: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

答案 3 :(得分:0)

使用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/

答案 4 :(得分:0)

这是我的递归函数,它不仅可以将数组的值更改为array_walk_recursive(),而且可以更改给定数组的键。它还保持数组的顺序: https://stackoverflow.com/a/57622225/10452175