Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flip two-dimensional associative array in PHP

I need to transform an array of parents to children into an array of children to parents. For example, I have an array like this:

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

And I want to turn it into this:

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

]

Is there a way to accomplish this task without using nested foreach loops? If not, what is the most efficient way to do so?

Thanks in advance!

like image 632
Raiden616 Avatar asked Dec 01 '16 13:12

Raiden616


2 Answers

Short solution using array_merge_recursive, array_combine and array_fill functions:

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

The output:

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
        )
)
like image 157
RomanPerekhrest Avatar answered Oct 26 '22 13:10

RomanPerekhrest


In terms of "efficiency" I believe a nested loop, in this case, is better:

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

Attempting to get creative with other functions like array_map may turn out to be slower, at least according to this answer. Might be worth running some of your own benchmarks.

like image 35
mister martin Avatar answered Oct 26 '22 13:10

mister martin