"Radiator", "details" => 0 => [ "label" => "Condition", "value" => "New"," /> "Radiator", "details" => 0 => [ "label" => "Condition", "value" => "New"," /> "Radiator", "details" => 0 => [ "label" => "Condition", "value" => "New","/>

How to filter multidimensional array based on column in a nested array?

108 Views Asked by At

Let's say I have an array that looks like this:

$array =    [    

    0 => [  
        "label"    =>  "Radiator",  
        "details"  =>   0 => [  
                            "label"     => "Condition",  
                            "value"     => "New",
                        ], 
                        1 => [  
                            "label"     => "Type",  
                            "value"     => "Wall",
                        ],
    ],  
    1 => [  
        "label"    =>  "Airco",  
        "details"  =>   0 => [  
                            "label"     => "Condition",  
                            "value"     => "New",
                        ], 
                        1 => [  
                            "label"     => "Type",  
                            "value"     => "",
                        ], 
    ], 
    2 => [  
        "label"    =>  "Refrigerator",  
        "details"  =>   0 => [  
                            "label"     => "Condition",  
                            "value"     => "Bad",
                        ], 
                        1 => [  
                            "label"     => "Type",  
                            "value"     => "Wall",
                        ], 
    ], 

];

I want to filter this array, so it only includes details where the value is not empty. The value for type of Airco is empty, so it should not return the detail type. The returned array should in this case look like this:

$array =    [    

    0 => [  
        "label"    =>  "Radiator",  
        "details"  =>   0 => [  
                            "label"     => "Condition",  
                            "value"     => "New",
                        ], 
                        1 => [  
                            "label"     => "Type",  
                            "value"     => "Wall",
                        ],
    ],  
    1 => [  
        "label"    =>  "Airco",  
        "details"  =>   0 => [  
                            "label"     => "Condition",  
                            "value"     => "New",
                        ],
    ], 
    2 => [  
        "label"    =>  "Refrigerator",  
        "details"  =>   0 => [  
                            "label"     => "Condition",  
                            "value"     => "Bad",
                        ], 
                        1 => [  
                            "label"     => "Type",  
                            "value"     => "Wall",
                        ], 
    ], 

];

I know I can filter an array based on an empty column with the following code (as found here):

$result = array_filter($array, function($o) use($column) {
    return trim( $o[$column] ) !== '' && $o[$column] !== null;
});

but as I have a nested array details I'm not quite sure how to adapt this code so it works for my case.

3

There are 3 best solutions below

3
Nageen On

Try this and will resolved the problem

$array =    [    

        [  
            "label"    =>  "Radiator",  
            "details"  =>   [[  
                                "label"     => "Condition",  
                                "value"     => "New",
                            ], 
                            [  
                                "label"     => "Type",  
                                "value"     => "Wall",
                            ]],
        ],  
        [  
            "label"    =>  "Airco",  
            "details"  =>   [[  
                                "label"     => "Condition",  
                                "value"     => "New",
                            ], 
                            [  
                                "label"     => "Type",  
                                "value"     => "",
                            ]], 
        ], 
        [  
            "label"    =>  "Refrigerator",  
            "details"  =>   [[  
                                "label"     => "Condition",  
                                "value"     => "Bad",
                            ], 
                            [  
                                "label"     => "Type",  
                                "value"     => "Wall",
                            ]], 
        ], 
    
    ];

Magic is here

    echo "Old Array<pre>";
    print_r($array);//die;
    $newArray = [];
    foreach($array as $key=>$value) {
        $deatilsInside = [];
        foreach($value['details'] as $key1=>$value1) {
            
            if($value1['value'] != '') {
                $deatilsInside[] = $value1;
            }
        }
        $value['details'] = $deatilsInside;
        $newArray[] = $value;
    }

    echo "New Array<pre>";
    print_r($newArray);die;

New Array Output

Array
(
    [0] => Array
        (
            [label] => Radiator
            [details] => Array
                (
                    [0] => Array
                        (
                            [label] => Condition
                            [value] => New
                        )

                    [1] => Array
                        (
                            [label] => Type
                            [value] => Wall
                        )

                )

        )

    [1] => Array
        (
            [label] => Airco
            [details] => Array
                (
                    [0] => Array
                        (
                            [label] => Condition
                            [value] => New
                        )

                )

        )

    [2] => Array
        (
            [label] => Refrigerator
            [details] => Array
                (
                    [0] => Array
                        (
                            [label] => Condition
                            [value] => Bad
                        )

                    [1] => Array
                        (
                            [label] => Type
                            [value] => Wall
                        )

                )

        )

)
0
Xander-Nova On

You can use array_map and array_filter to acomplish this:


$array = [
    [
        "label" => "Radiator",
        "details" => [
            [
                "label" => "Condition",
                "value" => "New",
            ],
            [
                "label" => "Type",
                "value" => "Wall",
            ],
            [
                "label" => "",
                "value" => "",
            ],
        ],
    ],
    [
        "label" => "Airco",
        "details" => [
            [
                "label" => "Condition",
                "value" => "New",
            ],
            [
                "label" => "Type",
                "value" => "",
            ],
        ],
    ],
    [
        "label" => "Refrigerator",
        "details" => [
            [
                "label" => "Condition",
                "value" => "Bad",
            ],
            [
                "label" => "Type",
                "value" => "Wall",
            ],
            [
                "label" => "",
                "value" => "asd",
            ],
        ],
    ],
];

$filteredArray = array_map(function ($item) {
    if (!empty($item["label"]) && !empty($item["details"])) {
        $details = array_filter($item["details"], function ($detail) {
            return !empty($detail["label"]) && !empty($detail["value"]);
        });

        $item["details"] = array_values($details);
        
        return $item;
    }
    return null;
}, $array);

$filteredArray = array_filter($filteredArray);

print_r($filteredArray);

Above code will remove 3rd array from Radiator, 2nd array from Airco and 3rd array from Refrigerator that have empty values for label, value or both.

4
nice_dev On

Your array_filter is only working on the first level. You would rather want to loop on details array too, which you can do using simple foreach loops. The outer loop will loop over all rows and the inner one over details of each row.

<?php

foreach($array as &$row){
    foreach($row['details'] as $key => $record){
        if(strlen($record['value']) == 0){
            unset($row['details'][$key]);
        }
    }
}

Live Demo