2016-12-01 6 views
6

Ich brauche eine Reihe von Eltern auf die Kinder in ein Array von Kindern zu den Eltern zu verwandeln. Zum Beispiel habe ich ein Array wie folgt aus:Flip zweidimensionale assoziatives Array in PHP

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

Und ich will sie in diesem drehen:

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

] 

Gibt es einen Weg, um diese Aufgabe zu erfüllen, ohne verschachtelte foreach-Schleifen zu verwenden? Wenn nicht, was ist der effizienteste Weg?

Vielen Dank im Voraus!

Antwort

5

Short-Lösung mit array_merge_recursive, array_combine und array_fill Funktionen:

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

Der Ausgang:

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

In Bezug auf die "Effizienz" Ich glaube, eine verschachtelte Schleife, in diesem Fall besser ist:

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

Versuch, c reative mit anderen Funktionen wie array_map kann sich als langsamer erweisen, zumindest nach this answer. Vielleicht lohnt es sich, einige Ihrer eigenen Benchmarks zu betreiben.

0

Verwenden von Closures und array_map (man kann nur hoffen, array_map wird schneller ausgeführt als die entsprechende for Zyklus ... ist es nicht eine native Funktion sein?).

$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";