web-dev-qa-db-ja.com

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)

ただし、キーは変更されません。配列をループしてキーと値を変更できる配列関数はありますか?

24
mithunsatheesh

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);
61
raina77ow

そのためには、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]);
}

インデックスのようなキーがないことに注意してください。

もう1つの方法は、参照を介して値を処理し、後でキーを設定することです。

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
hakre

$ piperから必要なキーと値を含む新しい配列を作成してみませんか?

$piper2 = array();
foreach ($piper as $k => $val)
{
  $splitted = explode("=", $val);
  $key = $splitted[0];
  $value = $splitted[1];

  $piper2[$key] = $value;
}

$piper = $piper2; // if needed
2
user1703809

これは、配列の値をarray_walk_recursive()として変更できるだけでなく、指定された配列のキーも変更できる再帰関数です。また、配列の順序も保持されます。 https://stackoverflow.com/a/57622225/10452175

0
James Bond

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/

0
B. Assem