2012-11-07 13 views
16

配列関数を使用して、パイプで区切られた文字列を連想配列に変換しています。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) 

が、キーは不変です。配列をループしてキーと値を変更できる配列関数はありますか?

+0

希望結果の配列は何ですか? –

+0

@JasonMcCreary:私はそれを更新しました – mithunsatheesh

+2

編集: "これは最速です"これは私の目の建設的な質問ではありません。以下の私のコメントを参照してください。 – hakre

答えて

43

(コールバック関数を記述する)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); 
+2

+1は 'use'に+1します。これにはPHP 5.3以降が必要です。 –

+0

これは、すでにコードを含んでいる簡単なforeach反復と比較してオーバーヘッドであり、スコープ間で変数を渡す必要はありません。 – hakre

+0

なぜこの目的のために単純なforeachではなくarray_walkを使用しますか? –

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の後にその問題を確認することができます。データが失われることはありません。

おそらく最も結果の配列にstroingによって簡素化され、次のforeachを保証することはできません何か:$パイパーから目的のキーと値を持つ新しい配列を構築しないのはなぜ

$result = array(); 
foreach ($piper as $value) { 
    list($key, $value) = explode("=", $value); 
    $result[$key] = $value; 
} 
+0

なぜ '$ piper'を再利用するのですか? –

+1

@ JasonMcCreary:2番目の例を追加しました。これは、より適合した値を再利用します。いずれにせよ、 '$ piper'は処理用ですので、再利用するのに問題はありません。 – hakre

+0

どちらを最速で実行するか教えてください。 foreachや正規表現か、それともarray_walkですか? – mithunsatheesh

3

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

を行います使用

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

    $piper2[$key] = $value; 
} 

$piper = $piper2; // if needed 
+0

どちらが最速に実行されるのか教えてください。 foreachや正規表現か、それともarray_walkですか? – mithunsatheesh

関連する問題