Harea Costea
Harea Costea

Reputation: 273

Count the number of value intersections between a 3d array and a flat array

I have two arrays:

$array1 = [
    [['host' => 'test1']],
    [['host' => 'test2']],
];

$array2 = [
    'test1',
    'ghfhfghfg',
];

Now I want to compare these arrays and return $nCount = 1 because test1 exists in both tables.

Upvotes: -1

Views: 94

Answers (4)

mickmackusa
mickmackusa

Reputation: 47894

It is not necessary to implement looped data preparations prior to checking for intersections. Just use array_uintersect() and on either side of the 3-way comparison operator attempt to access the value from one array otherwise fallback to the other array's value. Demo

echo count(
         array_uintersect(
             $array1,
             $array2,
             fn($a, $b) => ($a[0]['host'] ?? $a)
                 <=> ($b[0]['host'] ?? $b)
         )
     );
// 1

Alternatively, make calls of in_array() while filtering. Demo

echo count(
         array_filter(
             $array1,
             fn($set) => in_array($set[0]['host'], $array2)
         )
     );

Upvotes: 0

ymas
ymas

Reputation: 574

I tend to avoid hard-coding array indices if I can help it.

Will your first array structure always be the same?

I would write a function that would flatten the first array, for example:

    function flatten($arr, &$acc=array()) {
        if (empty($arr)) {
            return $acc;
        }   
        $e = array_pop($arr);
        if (is_array($e)) {
            flatten($e, $acc);
        } else {
            $acc[] = $e;
        }
        return flatten($arr, $acc);
    }

This flatten method would work for a more general case of your first array. The calls would be something like so:

    $ar = array(
        array(
            'test1',
        ),
        array(
            'test2',
        ),
     );

     $ar2 = array(
         'test1',
         'ghfhfghfg',
     );

     $same = array_intersect(flatten($ar), $ar2);
     var_dump($same);

You can add more checks for the flatten function.

Upvotes: 0

billyonecan
billyonecan

Reputation: 20250

You could do something like this:

count(array_intersect(array_map(function($a) { return $a[0]['host']; }, $array1), $array2));

Upvotes: 1

androidavid
androidavid

Reputation: 1259

First of all you have to know what's your input. In your case I assumed that you will always have the same type of multi-column "table" (as you call it).

For this case you can use something like the following which flattens the multi-column array to a flat array like the second one.

<?php
$multi_col = array(
    array(
        array(
            'host'=>'test1'
        )
    ),
    array(
        array(
            'host'=>'test2'
        )
    )
);

$single_col = array('test1', 'sfsd');
$single_cold_multicol = array_map(function(Array $item){
    return $item[0]['host'];
}, $multi_col);

$diff_compare = array_diff($single_col, $single_cold_multicol);
$nCount = count($single_col) - count($diff_compare);

In case youre $multi_col does not always have the same depth, you would need to recursively flatten. If it does always have the same depth (you always know how the array is built), you can just use the code above.

Upvotes: 0

Related Questions