Consolidate column values within each subset of a multidimensional array as comma separated values

37 views Asked by At

I have some trouble re-building a PHP array. I need to change it for printing a table to a PDF doc with tfPDF Library.

I tried it with foreach() loops, array_walk(), array_walk_recursive(), array_chunk() and array_slice() - so far without success.

This is my array $data:

$data = [
    "file_id" => 1394,
    "user_id" => 463466,
    "periode" => 2022,
    "costs" => 64.45,
    "values" => [
        "457" => [
            "1" => [
                "data_id" => 1,
                "supplier_id" => 457,
                "costs1" => 1000,
                "costs2" => 100,
                "group_name" => "7%",
            ],
            "140" => [
                "data_id" => 140,
                "supplier_id" => 457,
                "costs1" => 2000,
                "costs2" => 50,
                "group_name" => "19%",
            ],
            "197" => [
                "data_id" => 197,
                "supplier_id" => 457,
                "costs1" => 3000,
                "costs2" => 300,
                "group_name" => "special",
            ],
        ],
        "430" => [
            "490" => [
                "data_id" => 490,
                "supplier_id" => 430,
                "costs1" => 500,
                "costs2" => 30,
                "group_name" => "new 4",
            ],
            "552" => [
                "data_id" => 552,
                "supplier_id" => 430,
                "costs1" => 7000,
                "costs2" => 250,
                "group_name" => "new 5",
            ],
        ],
        "425" => [
            "1106" => [
                "data_id" => 1106,
                "supplier_id" => 425,
                "costs1" => 10,
                "costs2" => 4,
                "group_name" => "new 6",
            ],
        ],
    ],
];

For the print function the following format would be the best:

$pdf->Row(array(
    "data_id \n" .
    "data_id \n" .
    "data_id",

    "supplier_id \n" .
    "supplier_id \n" .
    "supplier_id",
                        
    "costs1 \n" .
    "costs1 \n" .
    "costs1",
                        
    "costs2 \n" .
    "costs2 \n" .
    "costs2",
                        
    "group_name \n" .
    "group_name \n" .
    "group_name",
));

So I need to change the $data to an array like this:

[
    'file_id' => 1394,
    'user_id' => 463466,
    'periode' => 2022,
    'costs' => 64.45,
    'values' => [
        457 => [
            'data_id' => '1, 140, 197',
            'supplier_id' => '457, 457, 457',
            'costs1' => '1000, 2000, 3000',
            'costs2' => '100, 50, 300',
            'group_name' => '7%, 19%, special',
        ],
        430 => [
            'data_id' => '490, 552',
            'supplier_id' => '430, 430',
            'costs1' => '500, 7000',
            'costs2' => '30, 250',
            'group_name' => 'new 4, new 5',
        ],
        425 => [
            'data_id' => 1106,
            'supplier_id' => 425,
            'costs1' => 10,
            'costs2' => 4,
            'group_name' => 'new 6',
        ],
    ],
]; 

Can you help me?

The last step would be the comma separation like this:

array_walk($data['values'], function (&$val) {
    $val[] = implode(", ", $val[]);
});
3

There are 3 answers

0
IT goldman On

A few loops and testings and it should work:

$values = $data['values'];
$result = [];
foreach ($values as $key1 => $value1) {
    $result[$key1] = [];
    foreach ($value1 as $key2 => $value2) {
        foreach ($value2 as $key3 => $value3) {
            $result[$key1][$key3][] = $value3;
        }
    }
    foreach ($result[$key1] as $key2 => $value2) {
        $result[$key1][$key2] = implode(', ', $value2);
    }
}
$data['values'] = $result;
print_r($data);
0
mickmackusa On

I would modify the original array, use nested loops to consolidate the structure, then update each subset of data in place.

Code: (foreach() Demo) (array_walk() Demo) (array_map() Demo)

foreach ($data['values'] as &$values) {
    $set = [];
    foreach ($values as $row) {
        if (!$set) {
            $set = $row;
        } else {
            foreach ($row as $k => $v) {
                $set[$k] .= ", $v";
            }
        }
        $values = $set;
    }
}
var_export($data);
0
Geert On

You could use array_combine to substract the values

$filtered_array = [];

function getValues($value) {
    $values_by_index = [];

    foreach($value as $dataset) {
        $values_by_index[$dataset['supplier_id']] = array_combine(['data_id', 'supplier_id', 'costs1', 'costs2', 'group_name'], $dataset);
    }

    return $values_by_index;
}

foreach($file['values'] as $key => $value) {
    $filtered_values = getValues($value);
    $filtered_array = array_merge($filtered_values, $filtered_array);
}

Even a better approach might be using the array_map function

$filtered_array = [];

foreach($file['values'] as $key => $value) {
    $filtered_array = array_merge(array_map(function($dataset) {
        return array_combine(['data_id', 'supplier_id', 'costs1', 'costs2', 'group_name'], $dataset);
    }, $value), $filtered_array);
}