简体   繁体   中英

php remove empty 'columns' in multidimensional, associative array

Goal: Generate an array that includes only those 'columns' with data, even though a 'header' may exist.

Example Data:

Array (
    [HeaderRow] => Array (
        [0] => Employee [1] => LaborHours [2] => 0.1 [3] => 0.25 [4] => 0.5 [5] => 0.8
    )
    [r0] => Array (
        [0] => Joe [1] => 5 [2] => [3] => [4] => 50 [5] =>
    ) 
    [r1] => Array (
        [0] => Fred [1] => 5 [2] => 10 [3] => [4] => [5] =>
    )
)

Desired Output:

Array (
    [HeaderRow] => Array (
        [0] => Employee [1] => LaborHours [2] => 0.1 [4] => 0.5
    )
    [r0] => Array (
        [0] => Joe [1] => 5 [2] => [4] => 50
    ) 
    [r1] => Array (
        [0] => Fred [1] => 5 [2] => 10 [4] =>
    )
)

So, in this very dumbed down example, the HeaderRow will always have data, but if both c0 and c1 are empty (as is the case for [3] and [5]) then I want to remove. I tried iterating through with for loops like I would in other languages, but that apparently doesn't work with associative arrays. I then tried doing a transpose followed by two foreach loops, but that failed me as well. Here's a sample of my for loop attempt:

Attempt with For Loop

for ($j = 0; $j <= count(reset($array))-1; $j++) {
    $empty = true;
    for ($i = 1; $i <= count($array)-1; $i++) {
        if(!empty($array[$i][$j])) {
            $empty = false;
            break;
        }               
    }
    if ($empty === true)
    {
        for ($i = 0; $i <= count($array); $i++) {
            unset($array[$i][$j]);
        }
    }
}       
return $array;

Attempt with transpose:

$array = transpose($array);
foreach ($array as $row)
{
    $empty = true;
    foreach ($row as $value)
    {
        if (!empty($value))
        {
            $empty = false;
        }
    }
    if ($empty) {
        unset($array[$row]);
    }
}
$array = transpose($array);
return $array;


    function transpose($arr) {
        $out = array();
        foreach ($arr as $key => $subarr) {
            foreach ($subarr as $subkey => $subvalue) {
                $out[$subkey][$key] = $subvalue;
            }
        }
        return $out;
    }

I know the transpose one isn't terribly fleshed out, but I wanted to demonstrate the attempt.

Thanks for any insight.

We can make this more simpler. Just get all column values using array_column . Use array_filter with a custom callback to remove all empty string values. If after filtering, size of array is 0 , then that key needs to be unset from all subarrays.

Note: The arrow syntax in the callback is introduced since PHP 7.4 .

Snippet:

<?php


$data = array (
    'HeaderRow' => Array (
        '0' => 'Employee','1' => 'LaborHours', '2' => 0.1, '3' => 0.25, '4' => 0.5, '5' => 0.8
    ),
    'r0' => Array (
        '0' => 'Joe', '1' => 5, '2' => '','3' => '', '4' => 50, '5' => ''
    ),
    'r1' => Array (
        '0' => 'Fred', '1' => 5,'2' => 10, '3' => '', '4' => '', '5' => ''
    )
);


$cleanup_keys = [];
foreach(array_keys($data['HeaderRow']) as $column_key){
    $column_values = array_column($data, $column_key);
    array_shift($column_values); // removing header row value
    $column_values = array_filter($column_values,fn($val) => strlen($val) != 0);
    if(count($column_values) == 0) $cleanup_keys[] = $column_key;
}

foreach($data as &$row){
    foreach($cleanup_keys as $ck){
        unset($row[ $ck ]);
    }
}
print_r($data);

It figures, I work on this for a day and have a moment of clarity right after posting. The answer was that I wasn't leveraging the Keys.:

function array_cleanup($array)
{
    $array = transpose($array);     
    foreach ($array as $key => $value)
    {
        $empty = true;
        foreach ($value as $subkey => $subvalue)
        {               
            if ($subkey != "HeaderRow") {
                if (!empty($subvalue))
                {
                    $empty = false;
                }
            }
        }
        if ($empty) {
            unset($array[$key]);
        }
    }
    $array = transpose($array);
    return $array;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM