Jackson
Jackson

Reputation: 483

Using array_filter to filter multidimensional array with another array

I have two arrays, the second is multidimensional. I'm trying to return a third array where the service_id in Array2 match the values in Array1.

Array1
(
    [0] => 158
    [1] => 162
)

Array2
(
    [localhost] => Array
        (
            [0] => Array
                (
                    [host_name] => localhost                        
                    [current_state] => 0                   
                    [service_id] => 158
                )

            [1] => Array
                (
                    [host_name] => localhost
                    [current_state] => 0                        
                    [service_id] => 159
                )
        )
    [192.168.0.43] => Array
        (
            [0] => Array
                (
                    [host_name] => 192.168.0.43                        
                    [current_state] => 0
                    [service_id] => 168
                )

            [1] => Array
                (
                    [host_name] => 192.168.0.43
                    [current_state] => 1
                    [service_id] => 162
                )
        )
)

So Array3 should be:

Array3
(
    [localhost] => Array
        (
            [0] => Array
                (
                    [host_name] => localhost                        
                    [current_state] => 0                   
                    [service_id] => 158
                )

     [192.168.0.43] => Array
        (
            [0] => Array
                (
                    [host_name] => 192.168.0.43
                    [current_state] => 0                   
                    [service_id] => 162
                )
        )
)

Here is what I have so far, but it doesn't appear to be filtering the entire array.

$Array3= array_filter($Array2, function ($value) use ($Array1) {
        return in_array(array_shift($value)['service_id'], $Array1);
});

Am I close here, What am I missing?

Upvotes: 0

Views: 53

Answers (2)

Nigel Ren
Nigel Ren

Reputation: 57121

I think it's because you want to filer at a second depth that it needs to loop across the first level and then filter the second level (think that sort of makes sense).

So this code uses array_map() to loop over the host level of the array (localhost and 192.168.0.43) and then uses array_filter() within this. Have to use use() to pass the lookup array into each level of the function

$array3 = array_map(function($data) use ($Array1)
    { return array_filter($data, function($sub) use ($Array1)
        { return in_array($sub["service_id"], $Array1); });
}, $Array2);

print_r($array3);

prints...

Array
(
    [localhost] => Array
        (
            [0] => Array
                (
                    [host_name] => localhost
                    [current_state] => 0
                    [service_id] => 158
                )

        )

    [192.168.0.43] => Array
        (
            [1] => Array
                (
                    [host_name] => 192.168.0.43
                    [current_state] => 1
                    [service_id] => 162
                )

        )

)

Upvotes: 2

cmprogram
cmprogram

Reputation: 1884

So below should be what you need to achieve $Array3 :

$Array3 = array(array($Array2[0][0], $Array2[0][1], $Array1[0]), array($Array2[1][0],
$Array2[1][1], $Array1[1]));

However to achieve this more dynamically, you'd want to use something like :

$Array3 = array();

for($i = 0; $i < $Array2[0].length; $i++){

array_push($Array3, array($Array2[$i][0], $Array2[$i][1], $Array1[$i]));

}

var_dump($Array3) // For debug only.

Upvotes: 0

Related Questions