1

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.

3
  • Question writeup is pretty neat. Say If [3] is not empty for r0, but empty for r1, what would be your desired output in this case? Commented Aug 18, 2021 at 13:32
  • Keep. Sorry, I apparently only can get my brain to fire on all cylinders after posting a question, as I did figure it out just now. Thanks for the writeup comment. :) Commented Aug 18, 2021 at 13:36
  • Sure, I believe your code can be made more concise. Commented Aug 18, 2021 at 13:41

2 Answers 2

2

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);
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the cleanup suggestion. I'd contemplated a similar route, but ultimately couldn't figure out how to execute.
@SaintFrag Glad to help and see that my code is clean and readable to you.
0

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.