Antonios Lampros
Antonios Lampros

Reputation: 93

Use the first column of a 2d array as keys when transposing its data

I have the following array.

[
    ["Name", "name1", "name2"],
    ["Clean", "clean1", "clean2"],
    ["Mixed", "mixed1", "mixed2"],
    ["Incoming", "incoming1", "incoming2"]
];

I want to transpose the rows so that the first column becomes the new associative keys for all subsequent columns from the original array.

array(
    array('Name' => 'name1', 'Clean' => 'clean1', 'Mixed' => 'mixed1', 'Incoming' => 'incoming1'),
    array('Name' => 'name2', 'Clean' => 'clean2', 'Mixed' => 'mixed2', 'Incoming' => 'incoming2')
)

Upvotes: -1

Views: 53

Answers (2)

mickmackusa
mickmackusa

Reputation: 48031

A functional-style approach can use array_map() with the spread operator in two places for transposition, then isolate the first transposed row as keys before combining keys with subsequent transposed rows. The first returned row will be garbage, so unconditionally discard the first element. Demo

var_export(
    array_slice(
        array_map(
            function (...$col) {
                static $keys;
                if (!$keys) {
                    $keys = $col;
                    return [];
                }
                return array_combine($keys, $col);
            },
            ...$array
        ),
        1
    )
);

Much more simply, just use nested loops to transpose the structure and remove the keys before initiating the inner loop. Demo

$result = [];
foreach ($array as $row) {
    $k = array_shift($row);
    foreach ($row as $i => $v) {
        $result[$i][$k] = $v;
    }
}

var_export($result);

Upvotes: 0

ya_Bob_Jonez
ya_Bob_Jonez

Reputation: 38

According to the sample array, I represented it this way: s[r0=>rn, r0=>rn, r0=>rn, ...], s[...], ... for myself and came up with this code:

$array = [
    [
        "Name",
        "name1",
        "name2"
    ],
    [
        "Clean",
        "clean1",
        "clean2"
    ],
    [
        "Mixed",
        "mixed1",
        "mixed2"
    ],
    [
        "Incoming",
        "incoming1",
        "incoming2"
    ]
];
$res = [];
for($s = 0; $s < count($array[0])-1; $s++){
    foreach($array as $r => $row){
        $res[$s][$row[0]] = $array[$r][$s+1];
    }
}
print_r($res);

Not the best solution of course, but well, you can improve it on your own — I just pointed the basic one.

EDIT: simplified the code.

Upvotes: 0

Related Questions