2016-12-01 70 views
6

Potrzebuję przekształcić tablicę rodziców na dzieci w tablicę potomków dla rodziców. Na przykład, mam tablicę takich jak to:Odwróć dwuwymiarową tablicę asocjacyjną w PHP

[ 
    1 => [a,b,c], 
    2 => [b,c,d], 
    3 => [c,d,e], 
] 

I chcę, aby przekształcić go w ten sposób:

[ 
    a => [1], 
    b => [1,2], 
    c => [1,2,3], 
    d => [2,3], 
    e => [3] 

] 

Czy istnieje sposób, aby wykonać to zadanie bez używania zagnieżdżonych pętla foreach? Jeśli nie, jaki jest najskuteczniejszy sposób?

Z góry dziękuję!

Odpowiedz

5

Krótki rozwiązanie wykorzystujące array_merge_recursive, array_combine i array_fill funkcje:

$arr = [ 
    1 => ['a','b','c'], 
    2 => ['b','c','d'], 
    3 => ['c','d','e'], 
]; 

$result = []; 
foreach ($arr as $k => $v) { 
    $result = array_merge_recursive($result, array_combine($v, array_fill(0, count($v), [$k]))); 
} 

print_r($result); 

Wydajność:

Array 
(
    [a] => Array 
     (
      [0] => 1 
     ) 

    [b] => Array 
     (
      [0] => 1 
      [1] => 2 
     ) 

    [c] => Array 
     (
      [0] => 1 
      [1] => 2 
      [2] => 3 
     ) 

    [d] => Array 
     (
      [0] => 2 
      [1] => 3 
     ) 

    [e] => Array 
     (
      [0] => 3 
     ) 
) 
2

W kategoriach "wydajność" wierzę zagnieżdżonej pętli, w tym przypadku, jest lepsza;

$arr = [1 => ['a','b','c'], 
     2 => ['b','c','d'], 
     3 => ['c','d','e']]; 

$result = []; 
foreach ($arr as $key => $value) { 
    foreach ($value as $v) { 
     $result[$v][] = $key; 
    } 
} 

var_dump($result); 

Próba uzyskania c Reative z innymi funkcjami, takimi jak array_map może okazać się wolniejszy, przynajmniej według this answer. Może warto uruchomić niektóre z twoich benchmarków.

0

Używanie zamknięć i array_map (można mieć tylko nadzieję, że array_map działa szybciej niż odpowiadający cykl for ... czy to nie powinna być natywna funkcja?).

$multimap=[ 
    1 => [a,b,c], 
    2 => [b,c,d], 
    3 => [c,d,e], 
]; 

$result=[]; 
foreach($multimap as $k=>$arr) { 
    $callme=function($e) use (&$result, $k) { 
    if(! array_key_exists ($e, $result)) { 
     $result[$e]=[]; 
    } 
    $result[$e][]=$k; 
    return $e; // not that it matters what is returned, we're after the side-effects 
    }; 
    array_map($callme, $arr); 
} 

// just as yet another alternative to var_dump/print_r 
echo json_encode($result /*, JSON_PRETTY_PRINT */)."\n";