2012-11-07 68 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'。提醒這需要PHP 5.3+。 –

+0

好吧,這是比較簡單的foreach迭代,它已經包含代碼,並且不需要跨範圍傳遞變量。 – hakre

+0

爲什麼你會使用array_walk而不是一個簡單的foreach來達到這個目的? – 2012-11-07 14:01:31

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這可能是由stroing最簡化成一個結果數組保證:

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

爲什麼重用'$ piper'? –

+1

@JasonMcCreary:我添加了第二個例子,它重新使用了更合適的值。在任何情況下,'$ piper'都是用於處理的,所以我沒有看到使用(不重複使用)它的任何問題。 – hakre

+0

請建議我哪一個執行速度最快? foreach或正則表達式還是array_walk? – mithunsatheesh

3

爲什麼不建立一個具有從$吹笛所需的密鑰和值的新數組?

$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