2012-11-07 13 views
16

Używam funkcji tablicowych do konwertowania łańcucha rozdzielanego potokami do tablicy asocjacyjnej.zmiana kluczy tablicy w funkcji 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); 

to daje mi

array (size=4) 
    1 => string 'f' (length=1) 
    2 => string 't' (length=1) 
    3 => string 'r' (length=1) 
    4 => string 'm' (length=1) 

gdzie chcę:

array (size=4) 
    "k" => string 'f' (length=1) 
    "p" => string 't' (length=1) 
    "e" => string 'r' (length=1) 
    "t" => string 'm' (length=1) 

ale klucze są niezmienione. Czy istnieje funkcja tablicowa, za pomocą której można przechodzić przez tablicę i zmieniać również klucze i wartości?

+0

Co znajduje się żądany wynikającą tablicę? –

+0

@JasonMcCreary: zaktualizowałem to – mithunsatheesh

+2

Edycja: "Który jest najszybszy" sprawia, że ​​jest to teraz mało konstruktywne pytanie w moich oczach. Zobacz mój komentarz poniżej. – hakre

Odpowiedz

43

Mówi się w dokumentacji array_walk (opisujące funkcję callback):

tylko wartości tablicy może być potencjalnie zmieniły; jego struktura nie może być zmieniona, tj. programista nie może dodawać, usuwać ani zmieniać kolejności elementów . Jeśli wywołanie zwrotne nie spełnia tego wymagania, zachowanie tej funkcji jest niezdefiniowane i nieprzewidywalne.

Oznacza to, że nie można użyć array_walk do zmiany kluczy powtarzanej macierzy. Można jednak utworzyć nową tablicę z nim:

$result = array(); 
array_walk($piper, function (&$value,$key) use (&$result) { 
    $splitted = explode("=",$value); 
    $result[ $splitted[0] ] = $splitted[1]; 
}); 
var_dump($result); 

Mimo to, myślę, że jeśli to było do mnie, użyję tu wyrażenia regularnego (zamiast „Eksplodowanie eksplodowała”):

$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 dla "użycia". Przypomnienie to wymaga PHP 5.3+. –

+0

Cóż, jest to narzut w porównaniu do prostej iteracji foreach, która już zawiera kod i nie ma potrzeby przekazywania zmiennych w różnych zakresach. – hakre

+0

dlaczego chcesz używać array_walk, a nie proste foreach w tym celu? –

2

Możesz lepiej użyć do tego celu foreach. Poniższy przykład pokazuje przetwarzanie wpisu, dodawanie go za pomocą prawego klawisza i usuwanie oryginalnego wpisu.

$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]); 
} 

Uważaj, aby nie mieć kluczy, które są jak indeks.

Inną alternatywą jest do przetwarzania wartości poprzez odniesienie i ustawić klawisze potem:

foreach ($piper as &$value) { 
    list($keys[], $value) = explode("=", $value); 
} 
unset($value); 

$piper = array_combine($keys, $piper); 

nie doprowadzić cię do żadnych kłopotów, ale po prostu z duplikatów kluczy. Ale możesz sprawdzić ten problem po foreach, żadne dane nie zostaną utracone.

coś, co nie może być zagwarantowane z następujących foreach który prawdopodobnie jest najbardziej uproszczoną przez stroing do tablicy wynikowej:

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

Dlaczego warto ponownie użyć '$ piper'? –

+1

@JasonMcCreary: Dodałem drugi przykład, który ponownie używa wartości, która jest bardziej pasująca. W każdym razie '$ piper' jest do przetwarzania, więc nie widzę problemu z jego użyciem (nie można go ponownie użyć). – hakre

+0

proszę zasugerować mi, który z nich zostanie wykonany najszybciej? foreach lub regex, czy jest to array_walk? – mithunsatheesh

3

Dlaczego nie zbudować nową tablicę, która ma żądane klucze i wartości z $ 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

proszę zasugerować mi, który z nich będzie wykonywać najszybciej? foreach lub regex, czy jest to array_walk? – mithunsatheesh

Powiązane problemy